(十八)《汇编语言(王爽)》 | 检测点 11.1、11.2、11.3、11.4

本文详细介绍了标志寄存器在CPU运算过程中的作用,包括ZF、PF、SF、CF、OF等标志位的功能,并通过实例解析了如何利用这些标志位进行条件判断和流程控制。此外,还探讨了如何使用pushf和popf指令直接访问标志寄存器。
摘要由CSDN通过智能技术生成


1. 预备知识

标志寄存器的作用:(1)存储相关指令的某些执行结果;(2)为 CPU 执行相关指令提供行为依据;(3)控制 CPU 的相关工作方式。和其他寄存器用来存放数据不同,标志寄存器按位起作用,每一位都有特定的含义。标志寄存器中各标志位:

15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
            OF DF IF TF SF ZF    AF    PF    CF

标志寄存器只有在进行相关运算时起作用,mov 等转移指令不会引起标志寄存器值的变化。常用的标志寄存器:

  • ZF 记录指令执行后,其结果是否为 0。如果为 0 则 ZF 为 1,否则为 0。
  • PF 记录指令执行后,其结果所有二进制位中 1 的个数是否为偶数。如果为偶数则 PF 为 1,否则为 0。
  • SF 记录指令执行后,其结果是否为负。如果为负则 SF 为 1,否则为 0。
  • CF 记录无符号数的运算中,向更高位的进位值或从更高位的借位值。在判断标志位 CF 的值时,将原计算看作是无符号数的计算。
  • OF 记录有符号数的运算中,运算结果是否发生溢出。如果溢出则 OF 为 1,否则为 0。在判断标志位 OF 的值时,将原计算看作是有符号数的计算。如计算,add 0F0H, 088H,等价于 (-16) + (-120) = -136,超出了 8 位有符号数的表示范围。

adc 指令和 sbb 指令分别表示带进位的加法指令带借位的减法指令,即在运算时需带上标志位 CF 的值,如 +(CF) 和 -(CF)。adc 指令可用于针对溢出位数的加法,如先针对低位使用 add 指令相加,再针对次高位使用 adc 指令相加,最后针对最高位使用 adc 指令相加。

cmp 是比较指令,相当于完成减法功能,但是不保存结果,仅影响标志位的值。可以借由 cmp 指令实现高级语言中的 if 功能,格式为 cmp 对象1, 对象2。如 cmp ax,bx:

  • 如果 (ax)=(bx),则 ZF=1。
  • 如果 (ax)≠(bx),则 ZF=0。
  • 如果 (ax)<(bx),则减法计算将产生借位,CF=1。
  • 如果 (ax)≥(bx),CF=0。
  • 如果 (ax)>(bx),CF=0 且 ZF=0。
  • 如果 (ax)≤(bx),CF=1 或 ZF=1。

根据上述比较指令产生的结果,对应的转移指令如下:

指令含义检测的相关标志位
je等于则转移ZF=1
jne不等于则转移ZF=0
jb小于则转移CF=1
jnb不小于则转移CF=0
ja大于则转移CF=0 且 ZF=0
jna不大于则转移CF=1 或 ZF=1

DF 标志位为方向标志位,在串处理指令中,控制每次操作后 si 和 di 的增减。DF=0,每次操作后 si 和 di 递增;DF=1,每次操作后 si 和 di 递减。

pushf 的功能是将标志寄存器的值入栈;popf 的功能是从栈中弹出数据,并送入标志寄存器中。pushf 和 popf 为直接访问标志寄存器提供了一种方法。


2. 检测点 11.1

写出下面每条指令执行后,ZF、PF、SF 等标志位的值。

指令ZFPFSF
sub al,al110
mov al,1110
push ax110
pop bx110
add al,bl000
add al,10010
mul al010
  • 第一行,减法运算,结果为零;结果中 1 的个数为零,为偶数;结果不为负。
  • 第二 / 三行,转移指令,不影响标志寄存器的值。
  • 第四行,运算结果为寄存器 BX 的值,标志寄存器的值不变。
  • 第五行,AL 为 0001,BL 为 0001,结果为 0010。
  • 第六行,AL 为 0010,结果为 1100。
  • 第七行,8 位乘法。一个乘数默认放在 AL 中,另一个为指定值。即 (AL) * (AL),结果为 1001 0000,8 位乘法结果存放在 16 位寄存器 AX 中,内容为 0000 0000 1001 0000,表示正数。

3. 检测点 11.2

写出下面每条指令后,ZF、PF、SF、CF、OF 等标志位的值。

指令CFOFSFZFPF
sub al,al00011
mov al,10H00011
add al,90H00101
mov al,80H00101
add al,80H11011
mov al,0FCH11011
add al,05H10000
mov al,7DH10000
add al,0BH01101
  • 第一行,减法运算,结果为零。无进位 / 借位,无溢出。
  • 第二 / 四 / 六 / 八行,转移指令,不影响标志寄存器的值。
  • 第三行,加法运算,10H + 90H = 0A0H。结果 AL 的最高位为 1,表示负数。无进位 / 借位,无溢出。 1111 1100 + 0000 0101 = 0001 0000 0001
  • 第五行,加法运算,80H + 80H。对于有符号数的计算而言,(-128) + (-128) = -256,超出了 8 位有符号数的范围,有溢出;对于无符号数的计算而言,80H + 80H = 100H,有向更高位进位,且 AL 只能存储 00H 部分。
  • 第七行,加法运算,0FCH + 05H。对于有符号数的计算而言,(-4) + (5) = 01H,无溢出;对于有符号数的计算而言,FCH + 05H = 101H,有向更高位进位,且 AL 只能存储 01H 部分。
  • = 101H,但 AL 只能存储 01H 部分。有向更高位的进位,无溢出。0111 1101 + 0000 1011 =
  • 第九行,加法运算,7DH + 0BH。对于有符号数的计算而言,(125) + (11) = 136,超出了 8 位有符号数的范围,有溢出;对于无符号数的计算而言,7DH + 0BH = 88H,无向更高位的进位。结果 AL 的最高位为 1,表示负数。

4. 检测点 11.3

(1)补全下面的程序,统计 F000:0 处 32 个字节中,大小在 [32, 128] 的数据的个数。

	mov ax,0f000h
	mov ds,ax
	mov bx,0
	mov dx,0
	mov cx,32
s:
	mov al,[bx]
	cmp al,32
	___________
	cmp al,128
	___________
	inc dx
s0:
	inc bx
	loop s

由 mov al,[bx] 可知,每次使用寄存器 BX 从内存单元取值,s0 部分用于从内存单元中取值,则寄存器 DX 用于统计大小在 [32, 128] 的数据的个数。则,如果所取数据 [bx] 同时满足大于等于 32 和小于等于 128 时执行 inc dx 指令,否则直接执行 s0 部分的代码。所以,如果 cmp 比较指令任意一处不满足上述关系,则直接跳转到 s0 处。结合预备知识部分,当 (al) < 32 或 (al) > 128 时跳转到 s0 处,分别对应的转移指令为 jb 和 ja。代码段部分为:

	mov ax,0f000h
	mov ds,ax
	mov bx,0
	mov dx,0
	mov cx,32
s:
	mov al,[bx]
	cmp al,32
	jb s0
	cmp al,128
	ja s0
	inc dx
s0:
	inc bx
	loop s

(2)补全下面的程序,统计 F000:0 处 32 个字节中,大小在 (32, 128) 的数据的个数。

	mov ax,0f000h
	mov ds,ax
	mov bx,0
	mov dx,0
	mov cx,32
s:
	mov al,[bx]
	cmp al,32
	___________
	cmp al,128
	___________
	inc dx
s0:
	inc bx
	loop s

和上一题的分析类似,代码段部分为:

	mov ax,0f000h
	mov ds,ax
	mov bx,0
	mov dx,0
	mov cx,32
s:
	mov al,[bx]
	cmp al,32
	jna s0
	cmp al,128
	jnb s0
	inc dx
s0:
	inc bx
	loop s

5. 检测点 11.4

下面的程序执行后:(ax)=?

mov ax,0
push ax
popf
mov ax,0fff0h
add ax,0010h
pushf
pop ax
and al,11000101B
and ah,00001000B
  • 第三条语句 popf 将栈中数据 0 弹出,并送入标志寄存器,此时标志位全部置零。
  • 第四 / 五条语句,加法运算,0FFF0H + 0010H。对于有符号数的计算而言,(-16) + (16) = 0,无溢出,OF=0;对于无符号数的计算而言,(65520) + (16) = 65536,有向更高位的进位,CF=1。且 ZF=1,PF=1。
  • 语句 pushf 将标志寄存器的内容入栈,此时标志寄存器的内容为 0000 0000 0100 0101,则后续出栈后 (AX)=0045H。
  • and al,11000101B 进行按位与运算,结果为 (AL)=0100 0101=45H;and ah,00001000B 进行按位与运算,结果为 (AH)=0000 0000H。所以,最终 (AX)=0045H

6. 总结

  • 本文主要用到标志寄存器中 ZF、PF、SF、CF 和 OF 的功能。其中 OF 针对有符号数的运算检测是否有溢出,CF 针对无符号数的运算检测是否存在进位和借位。
  • 结合标志寄存器中各标志位的功能,cmp 比较指令和转移指令可以轻松实现高级语言中的 if 语句功能。
  • pushf 和 popf 直接作用于标志寄存器。

  • 30
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值