标志寄存器的典型指令

adc指令

  • adc是带进位加法指令,它利用了CF位上记录的进位值
  • 指令格式:adc 操作对象 1,操作对象 2
  • 功能:操作对象1=操作对象1+操作对象2+CF
  • 比如指令 adc,ax,bx 实现的功能是:(ax)=(ax)+(bx)+CF

CPU为什么要提供这样的一条指令?

  • 如果CF的值是被sub指令设置的,那么它的含义就是借位值
  • 如果是被add指令设置的,那么它的含义就是进位值
  • 我们来看一下两个数据:0198H和0183H如何相加的:

在这里插入图片描述
可以看出,加法可以分为两步来进行:

  • 低位相加
  • 高位相加再加上低位相加产生的进位值
    adc指令和add指令相配合就可以对更大的数据进行加法运算
    编程,计算1EF000H+201000H,结果放在ax(高16位)和bx(低16位)中
    因为两个数据的位数都大于16,用add指令无法进行计算,我们将计算机分两步进行,先将低16位相加,然后将高16位和进位值相加
mov ax,001EH
mov bx,0F000H
add bx,1000H
adc ax,0020H

sbb指令

  • sbb是带借位减法指令,它利用了CF位上记录的借位值
  • 指令格式:sbb 操作对象1,操作对象2
  • 功能:操作对象 1=操作对象 1-操作对象2-CF
  • 比如指令 sbb ax,bx 实现的功能是:(ax)=(ax)-(bx)-CF

cmp指令

  • cmp是比较指令,cmp的功能相当于减法指令,只有不保存结果,cmp指令执行后,将对标志寄存器产生影响,其他相关指令通过识别这些被影响的标志寄存器来得知比较结果
  • cmp指令格式:cmp 操作对象1,操作对象2
  • 功能:计算操作对象 1-操作对象 2 但并不保存结果,仅仅根据计算结果对标志寄存器进行设置
  • 比如,指令 cmp ax,ax,做(ax)-(ax)的运算,结果为0,但并不在ax中保存,仅影响flag的相关指令,指令执行后:zf=1,pf=1,sf=0,cf=0,of=0

这时候,我们能不能得到一个结论:cmp指令执行后,sf=1,就说明操作对象 1<操作对象 2
当然不能

  • 我们知道,实际结果的正负,之所以不能说明逻辑上真正结果的正负,关键的原因在于发生了溢出,如果没有溢出发生的话,那么实际结果的正负和逻辑上真结果的正负就一致了

我们以cmp ah,bh为例,总结一下CPU执行cmp指令后,sf和of的值是如何来说明比较结果的.

  • 1.如果sf=1,而of=0
    of=0,说明没有溢出,逻辑上真正结果的正负=实际结果的正负
    所以(ah)<(bh)
  • 2.如果sf=1,而of=1
    of=1,说明有溢出,因为sf=1,实际结果为负,如果因为溢出导致了实际结果为负,那么逻辑上真正的结果必然为正,说明(ah)>(bh)

后面同理可得

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

CPU提供了其他条件转移指令,大多数条件转移指令都检测标志寄存器的相关标志位,根据检测的结果来决定是否修改IP,这些条件转移指令通常都和cmp相配合使用,就好像call和ret指令通常相配合使用
下面常用的根据无符号数的比较结果进行转移的条件转移指令

指令含义检测的相关标志位
je等于则转移zf=1
jne不等于则转移zf=0
jb低于则转移cf=1
jnb不低于则转移cf=0
ja高于则转移cf=0且zf=0
jna不高于则转移cf=1或zf=1

注意观察一下它们所检测的标志位,都是cmp指令进行无符号数比较的时候,记录比较结果的标志位,比如je,检测zf位,当zf=1的时候进行转移,如果在je前面使用了cmp指令,那么je对zf的检测,实际上就是间接的检测cmp的比较结果是否为两数相等。

DF标志和串传送指令

flag的第10位是DF,方向标志位,在串处理指令中,控制每次操作后si,di的增减。

  • df=0,每次操作后si,di递增
  • df=1,每次操作后si,di递减

我们来看下面的一个串传送指令
格式:movsb
功能:执行movsb指令相当于进行下面几步操作

  • ((es)*16+(di))=((ds)*16+(si))
  • 如果df=0则:(si)=(si)+1 (di)=(di)+1
  • 如果df=1则:(si)=(si)-1 (di)=(di)-1
    可以看出,movsb的功能是将ds:si指向的内存单元中的字节送入es:di中,然后根据标志寄存器df位的值,将si和di递增或递减
    当然,也可以传送一个字,相关指令为movsw

movsb和movsw进行的是串传送操作中的一个步骤,一般来说,movsb和movsw都和rep配合使用,格式如下:
rep movsb
用汇编语法来描述rep movsb的功能就是:

s:	movsb
	loop s

可见,rep的作用是根据cx的值,重复执行后面的串传送指令,由于每执行一次movsb指令si和di都会递增或递减指向后一个单元或前一个单元,则rep movsb就可以循环实现(cx)个字符的传送
8086CPU提供了两条指令对df位进行设置
cld指令:将标志寄存器的df位置0
std指令:将寄存器的df位置1

pushf和popf

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

标志寄存器在Debug中的表示

在这里插入图片描述
下面列出Debug对我们已知的标志位的表示:

标志值为1的标记值为0的标志
ofOVNV
sfNGPL
zfZRNZ
pfPEPO
cfCYNC
dfDNUP
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值