首页 > 其他分享 >四、常用寄存器

四、常用寄存器

时间:2024-10-30 15:46:49浏览次数:1  
标签:常用 16 mov 地址 寄存器 ax bx

DS:内存段地址寄存器

段地址、偏移地址与物理地址

  1. 内存中数据的地址由段地址和偏移地址组成,其中段地址乘以16再加上偏移地址就是真实的物理地址。

    对于16进制的数来说,乘以十六就是整体向左移一位,例如:0xFE * 16 = 0xFE0

  2. 物理地址可以由多种段地址+偏移地址组合而成

    例如物理地址:0x21F60都可以由下面段地址+偏移地址表示

    段地址 偏移地址
    0x2000 0x1F60
    0x2100 0x0F60
    0x21F0 0x0060
    0x21F6 0x0000
    0x1F00 0x2F60

操作DS

读写内存与DS寄存器的关系

读写内存中的数据需要知道该内存的地址,而地址是段地址+偏移地址组成的,其中段地址在ds寄存器中,偏移地址由手动指定。

我们指定偏移地址后,程序自动在ds中取出段地址,与我们指定的偏移地址组成实际的物理地址,从而操作该地址的数据。

所以在访问内存的数据前,要先设置ds段地址寄存器,再手动指定偏移地址

设置DS寄存器的注意事项

在8086CPU中,ds不支持直接将立即数放到ds中,要用另一个寄存器传输数据

mov bs,21f6		// 不支持这样写

mov ax,21f6		// 把段地址先写入另一个寄存器
mov ds,ax		// 再通过寄存器与寄存器传输数据的方式为ds传输数据

示例:操作0x21F60处的数据

mov ax,21f6
mov ds,ax		// 设置段地址为0x21f6
mov ax,[0]		// 设置偏移地址为0x0000,对应的物理地址为:0x21F60。并将该地址的值复制到ax中

image

add al,[0]		// 0x21f60处的值加上al中的值,结果放到al中
mov [0],bl		// 把bl的值复制到0x21f60
add [0],bh		// bh加上0x21f60处的值,结果放到0x21f60

CS-IP:代码地址寄存器

作用:CS存的是段地址,IP存的是偏移地址,代码从这两个寄存器指向的地址开始运行

示例:在地址:0x20000处写代码,并改变CS-IP寄存器,从0x20000处开始运行代码

image

JMP指令:在代码中改变程序运行的位置

示例:

  • 在代码中改变程序运行的位置为:0x20000(CS和IP一起改变)

    jmp 2000:0000	// cs设置为0x2000,IP设置为0x0000
    

    image

  • 只改变IP

    jmp 3	// 只设置IP为0x0003,CS不变
    

    image

利用JMP指令写一个死循环
使用a 2000:0 指令将代码写在地址0x20000处

在运行代码前将CS-IP设置为:2000:0000。

mov ax,00
inc ax
mov bx,ax
jmp 3

SS-SP:栈顶地址寄存器

栈的概念

先进后出

入栈:

image

出栈:

image

栈顶元素的地址

CPU要进行入栈和出栈的操作,就需要知道栈顶元素的地址,而SS-SP寄存器存放的就是栈顶元素的地址,其中SS为段地址,SP为偏移地址

设置SS-SP寄存器就是设置栈顶的地址

示例:设置栈顶地址为:0x10010

mov ax,1000
mov bx,0010
mov ss,ax		// 设置栈顶地址的段地址
mov sp,bx		// 设置栈顶地址的偏移地址

PUSH指令:入栈

注意:

  • 入栈时,栈顶从高地址向低地址增长

  • 栈操作都是以字为单位的,也就是16位数据

  • 每一次入栈SP都会减2,因为栈空间是16位的

  • 入栈时,高位先入栈,低位后入

  • 如果想将地址:0x10000~0x1000F作为栈空间,那么栈顶地址要设置为:0x10010。也就是栈顶地址比栈的起始地址大一,如下图

    image

示例:

// 设置栈顶地址
mov ax,1000
mov bx,0010
mov ss,ax		// 设置栈顶地址的段地址
mov sp,bx		// 设置栈顶地址的偏移地址

// 入栈
mov ax,0123
mov bx,2266
mov cx,1122
push ax		// 将ax中的值放到栈顶
push bx		// 将bx的值放到栈顶
push cx		// 将cx的值放到栈顶

使用d 1000:0000 F命令查看地址0x10000~0x1000F之间的数据

image

POP指令:出栈

沿用上面入栈代码运行后的栈空间、栈空间中的元素及栈顶地址

注意:

  • 每一次出栈SP都会加2
  • 栈操作都是以字为单位的,也就是16位数据

示例:

pop ax	// 取出栈顶的元素放到ax中
pop bx	// 取出栈顶的元素放到bx中
pop cx	// 取出栈顶的元素放到cx中

image

出栈入栈完整示意图

image

栈顶越界

8060没有记录栈顶上限和栈底的寄存器,需要我们使用时自己注意不要让栈越界

SI、DI、BX、BP:寻址

BX作为偏移地址

bx中的值也可以表示为偏移地址,如下

mov ax,1000
mov ds,ax		// 设置段地址为1000
mov bx,0010
mov ax,[bx]		// 把bx中的值当偏移地址,也就是将地址0x10010的值复制到ax中
mov cx,[bx+2]	// 把bx中的值加2后当做偏移地址
mov cx,[bx-5]	// 把bx中的值减5后当做偏移地址

注意:bx为偏移地址时,他的段地址在DS寄存器中

BP与BX的区别

BP与BX一样,都是作为偏移地址,也可以加减立即数

  • 只不过BX作为偏移地址时,段地址是DS寄存器中的值;
  • 而BP作为偏移地址时,段地址是SS寄存器中的值。也就是说BP操作的是栈

示例:

  1. 设置DS为:0x3000,SS为:0x1000

    image

  2. 运行如下代码

    mov ax,1234
    mov cx,6789
    mov bp,0000
    mov bx,0000
    mov [bp],ax		// 将ax的值放到地址0x10000处
    mov [bx],cx		// 将cx的值放到地址0x30000处
    
  3. 验证结果

    image

SI、DI与BX、BP

SI和DI有这与BX一模一样的作用和写法,可以单独使用,也可以加减立即数,默认段地址也是DS寄存器

与BX不同的是SI、DI可以单独与BX或BP相加,如下

mov ax,[si]
mov ax,[si+1]
mov ax,[di]
mov ax,[di+2]

mov ax,[bx+si]
mov ax,[bx+di]
mov ax,[bx+si+2]
mov ax,[bx+di+3]

// si或bi与bp相加后,默认段地址会变成ss
mov ax,[bp+si]
mov ax,[bp+di]
mov ax,[bp+si+1]
mov ax,[bp+di+4]

注意:si和di不能同时出现,以下写法都是错误的

mov ax,[si+bi]		// 错误的
mov ax,[bx+si+bi]	// 错误的
mov ax,[bp+si+bi]	// 错误的

寻址总结

其中:EA表示偏移地址;SA表示段地址;idata表示立即数

image

[bx].idata = [bx+idata]
idata[si] = [si+idata]
idata[di] = [di+idata]
[bx][idata] = [bx+idata]
[bx][si] = [bx+si]
[bx].idata[si] = [bx+idata+si]
idata[bx][si] = [bx+si+idata]

标志寄存器

概述

image

标志位寄存器在debug中的表现

标志位寄存器 值为1时的表现 值为0时的表现
OF OV NV
SF NG PL
ZF ZR NZ
PF PE PO
CF CY NC
DF DN UP

ZF:零标志位

作用:记录相关指令执行后,其结果是否为0。如果结果为0,那么zf = 1;如果结果不为0,那么zf = 0

示例:

mov ax,1	// 设置ax的值为1
dec ax		// ax自减1
inc ax		// ax自增1

image

PF:奇偶校验位

作用:相关指令执行后,其结果的所有位中1的个数是否为偶数。如果1的个数为偶数,pf=1;如果为奇数,那么pf=0。

示例:

mov ax,0	// 设置ax的值为0
inc ax		// 结果为:0x01,1的位数为奇数
dec ax		// 结果为:0x00,1的位数为偶数

image

SF:符号标志位

作用:记录相关指令执行后,其结果是否为负。如果结果为负,sf=1;如果非负,sf=0

计算机中表示正负数:

  • 最高位为0,表示这个数是正数。直接转化为十进制就是结果

  • 最高位为1,表示这个数是负数。对他按位取反后加一(也就是求补),转化为十进制后再加上负号就是结果

  • 对于同一个二进制,计算机可以将他当做无符号数据,也可以当做有符号数据

    例如:

    00000001B,可以看作为无符号数1,或有符号数+1

    10000001B,可以看作为无符号数129,也可以看作有符号数-127.

总结:SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据的正负。在我们将数据当作有符号数来运算的时候,可以通过它来得知结果的正负。如果我们将数据当作无符号数来运算,SF的值则没有意义,虽然相关的指令影响了它的值。

示例:

mov al,3
sub al,5	// 3-5 = -2为负数
add al,10	// -2+16 = 14为正数

image

CF:进位标志位

作用:一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。

image

示例:

  • 进位

    mov al,ff
    mov bl,22
      add al,bl	// al+bl = 0x121,发生了进位
    

    image

  • 借位

    mov al,01
    mov bl,02
    sub al,bl
    

    image

OF:溢出标志位

溢出的概念:在进行有符号数运算的时候,如结果超过了机器所能表示的范围称为溢出。

​ 例如:两个八位数98和99相加,其结果为197,显然该结果超过了8位有符号数可以表示的范围:-128~127。这就是相加溢出。相减的溢出也是同理

​ 如果在进行有符号数运算时发生了溢出,那么结果将不正确,如下:

98+99=197=0xC5。0xC5在计算机中用有符号数表示为-59,这结果显然是错误的

作用:由于在进行有符号数运算时,可能发生溢出而造成结果的错误。则CPU需要对指令执行后是否产生溢出进行记录。因此有了溢出标志位。一般情况下,OF记录了有符号数运算的结果是否发生了溢出。如果发生溢出,OF=1;如果没有,OF=0。

示例:

  • 相加溢出

    mov al,62	// 正数98
    mov bl,63	// 正数99
    add al,bl	// 0x62+0x63=0xC5;98+00=-59,发生了溢出
    

    image

  • 相减溢出

    mov al,f0	// -16的补码
    mov bl,78	// 正数120
    sub al,bl	// 0xf0-0x78=0x78;-16-120=120,这结果明显不对,发生溢出
    

    image

进位和溢出标志位的区别

CF和OF所表示的进位和溢出,是分别对无符号数有符号数运算而言的,它们之间没有任何关系。

image

基于标志位的运算

ADC指令:带进位的加法

image

作用:用来计算很大的数据

示例:

  • 计算:0x1EF000 + 0x201000,结果放到ax(高16位)和bx(低16位)中

    这两个数据都大于16位,用add指令无法直接计算。

    所以要将计算分为两步,先将低16位相加,然后再将高16位及进位值相加,如下

    mov ax,001e		// 将0x1EF000 的高位放到ax中
    mov bx,f000		// 将0x1EF000 的低位放到bx中
    add bx,1000		// 用add指令将低16位相加,他们产生的进位会记录到cf中
    adc ax,0020		// 用adc指令将高16位及进位值相加
    

    image

    adc指令执行后也可能会进位,也可以对cf进行设置。这样,我们就可以对任意大的数进行相加

  • 计算:0x1EF0001000 + 0x2010001EF0,结果放在ax(最高16位),bx(次高16位),cx(低 16 位)中。

    mov ax,001e
    mov bx,f000
    mov cx,1000
    add cx,1ef0	// 先将低16位相加,完成后,CF中记录本次相加的进位值
    adc bx,1000	// 再将次高16位和CF(来自低16位的进位值)相加,完成后,CF中记录本次相加的进位值
    adc ax,0020	// 最后高16位和CF(来自次高16位的进位值)相加,完成后,CF中记录本次相加的进位值
    

    image

    使用计算机验证:

    image

SDD指令:带借位的减法

image

作用:用来计算很大的数据

示例:计算:0x003E1000 - 0x00202000,结果放到ax和bx中

mov ax,003e
mov bx,1000
sub bx,2000
sbb ax,0020

image

使用计算机验证

image

CMP指令:比较指令

image

作用:比较两个数的大小。本质上cmp的功能相当于减法指令,只是不保存结果,cmp指令执行后,将对标志位寄存器产生影响。其他指令通过识别这些被影响的寄存器位来得知比较结果

  • 无符号数比较

    假设要比较的两个数存放在ax和bx中,执行指令:cmp ax,bx

    结果 标志位 描述
    ax = bx zf = 1 计算结果为0
    ax != bx zf = 0 计算结果不为0
    ax < bx cf = 1 计算结果产生借位
    ax >= bx cf = 0 计算结果没有借位
    ax > bx cf = 0 且 zf = 0 计算结果没有借位且不为0
    ax <= bx cf = 1 或 zf = 1 计算结果产生借位或结果为0
  • 有符号数比较

    结果 标志位
    ax = bx zf = 1
    ax != bx zf = 0
    ax < bx (sf = 1且 of = 0) 或 (sf = 0 且 of = 1)
    ax > bx sf = 1且 of = 1
    ax >= bx sf = 0 且 of = 0
    ax <= bx (sf = 1且 of = 0 或 zf = 1) 或 (sf = 0 且 of = 1或 zf = 1)

    逻辑如下:

    image

检测比较结果的条件转移指令

转移指的是能修改IP寄存器,而条件指的是可以根据某种条件,决定是否修改IP

image

示例:

如果ah = bh,则ah = ah+ah,否则ah = ah+bh

cmp ah,bh
je s			// 判断ah是否等于bh,如果等于,则跳转到标号s处执行指令
add ah,bh		// 如果不是,则执行该指令
jmp short ok	// 跳转到ok处执行指令
s:add ah,ah
ok:...

其他指令同上

汇编语言寄存器的英文全称中文对照表

16位寄存器

寄存器 英文全称 中文描述
AX(AL&AH) accumulator 累加寄存器
BX(BL&BH) base 基址寄存器
CX(CL&CH) count 计数寄存器
DX(DL&DH) data 数据寄存器
SP stack pointer 堆栈指针寄存器
BP base pointer 基址指针寄存器
SI source index 源变址寄存器
DI destination index 目的变址寄存器
IP instruction pointer 指令指针寄存器
CS code segment 代码段寄存器
DS data segment 数据段寄存器
SS stack segment 堆栈段寄存器
ES extra segment 附加段寄存器

标志位寄存器

寄存器 英文全称 中文描述
OF overflow flag 溢出标志位。溢出时为1
SF sign flag 符号标志位。为负时为1
ZF zero flag 零标志位。为0时为1
CF carry flag 进位标志位。进位或借位时为1
AF auxiliary carry flag 辅助进位标志位。第三位向第四位进位时为1
PF parity flag 奇偶标志位。1的位数为偶数时为1
DF direction flag 方向标志位。DF为1时,操作后使SI和DI减小,反之则增大
IF interrupt falg 中断标志位。为1时允许响应中断
TF trap flag 陷阱标志位。用于调试单步模式

标签:常用,16,mov,地址,寄存器,ax,bx
From: https://www.cnblogs.com/liuhousheng/p/18515982

相关文章

  • 【GiraKoo】常用编码的对比(ASCII,GB2312,GBK,GB18030,UCS,Unicode)
    甯哥敤缂栫爜鐨勫姣旓紙ASCII锛孏B2312锛孏BK锛孏B18030锛孶CS锛孶nicode锛�鍦ㄧ▼搴忓紑鍙戜腑锛屾枃瀛楃紪鐮佷竴鐩存壆婕旂潃浜虹暅鏃犲锛屽嵈鑳屽悗鎹呬竴鍒€鐨勮鑹层€�鍙兘鍦ㄦ簮浠g爜鏂囦欢涓紝娉ㄩ噴鑾悕鍏跺鍦板彉鎴愪簡涔辩爜銆�鍙兘鏄彂閫佺粰鍒......
  • 【GiraKoo】C++编译中常用的内置宏
    开源项目:https://girakoo.com/联系方式:[email protected]简介针对不同的平台,很多头文件,函数名称,类型占用空间不一致。为了保证跨平台可编译,经常需要在项目中使用宏进行区分系统宏操作系统可使用的宏Windows32位_WIN32Windows64位_WIN32;_WIN64Linux__linu......
  • 常用函数
    1.算数函数    ABS-绝对值      ABS(x)当ABS函数的参数为NULL时,返回值也是NULL    MOD-求余数      MOD(被除数,除数)    ROUND-四舍五入      ROUND(对象数值,保留小数的位数)2.字符串函数    CONCAT-拼接      CONCAT(str1......
  • Java中常用的监控命令
    Java提供了多种监控工具,这些工具包含了许多命令行工具,用于监控、诊断和管理Java应用程序的性能。这些工具主要位于Java安装目录下的bin文件夹中,以下是几个常用的Java自带监控命令的详细说明:1.jps(JavaVirtualMachineProcessStatusTool)用于列出当前运行的......
  • 三、常用汇编指令
    MOV指令作用:数据移动movcx,ax //将ax寄存器中的值复制到cx寄存器中movdx,FFFF //将数据0xFFFF放到寄存器dx中moval,bh //将bx寄存器的高八位的数据复制到ax寄存器的低八位NOP:空指令指令、数据对齐可以有效地提高程序的性能,使用NOP指令,可以使得指令按字对齐,......
  • 二、DEBUG模式及常用指令
    debug概述debug是DOS、Windows都提供的实模式(8086方式)程序的调试工具。使用他可以查看CPU各种寄存器中的内容、内存的情况和在机器码级跟踪程序的运行debug的功能调试(Debug)的命令比较多,共有20多个,但这6个命令是和汇编学习密切相关的。在以后的实验中,我们还会用到一个P命令。......
  • Linux常用信息收集命令
    查看Linux系统内核信息uname-a查看Linux操作系统版本信息cat/proc/version查看Linux操作系统发行版信息lsb_release-acat/etc/issuecat/etc/redhat-release查看设备型号sudo/usr/sbin/dmidecode-ssystem-product-name查看CPU相关信息CPU数量:cat/pro......
  • 十五、PyTorch常用工具模块
      在训练神经网络过程中,需要用到很多工具,其中最重要的三部分是:数据、可视化和GPU加速。本章主要介绍Pytorch在这几方面的工具模块,合理使用这些工具能够极大地提高编码效率。1.1数据处理  在解决深度学习问题的过程中,往往需要花费大量的精力去处理数据,包括图像、文本、语音......
  • jenkins 常用shell
    1、发布前端shellip="192.168.31.33"port=22#前端打包后的包名dist_name="dist"#app的名字,app下有index.htmlapp_name="dist"#app所在的目录app_dir="/data/project/html/nmg-ibuilds-pc-visitor"#备份个数bak_count=3#备份目录bak_dir="/dat......
  • 函数调用寄存器及栈帧结构
    函数调用X86下,遵循被调用者使用规则,函数在调用子函数之前,保存相关寄存器的内容。函数调用时,参数先入栈,接着为返回地址入栈,BP寄存器入栈、再接着就是子函数的局部变量之类的了。常用寄存器栈帧结构函数调用时栈帧结构......