0x31:adc指令和sbb指令
adc是带进位加法指令,它利用了CF位上记录的进位值。
指令格式:adc 操作对象1, 操作对象2
功能:操作对象1 = 操作对象1 + 操作对象2 + CF
1 | mov ax, 2 |
1 | ;计算1EF000H+201000H,结果放在ax(高16位)和bx(低16位)中。 |
sbb指令
sbb是带借位减法指令,它利用了CF位上记录的借位值。
指令格式:sbb 操作对象1, 操作对象2
功能:操作对象1 = 操作对象1 - 操作对象2 - CF
1 | ;计算 003E1000H - 00202000H,结果放在ax,bx中,程序如下: |
0x32:cmp指令
cmp是比较指令,cmp的功能相当于减法指令,只是不保存结果。cmp指令执行后,将对标志寄存器产生影响。
其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
cmp指令格式:cmp 操作对象1,操作对象2
例如:
指令cmp ax, ax
,做(ax)-(ax)的运算,结果为0,但并不在ax中保存,仅影响flag的相关各位。
指令执行后:zf=1,pf=1,sf=0,cf=0,of=0。
CPU在执行cmp指令的时候,也包含两种含义:进行无符号数运算和进行有符号数运算。
0x33:检测比较结果的条件转移指令
可以根据某种条件,决定是否修改IP的指令。
jcxz它可以检测cx中的数值,如果(cx)=0,就修改IP,否则什么也不做。
所有条件转移指令的转移位移都是[-128,127]。(短转移)
多数条件转移指令都检测标志寄存器的相关标志位,根据检测的结果来决定是否修改IP。
这些指令可以分为对有符号数和无符号数的比较。
根据无符号数的比较结果进行转移的条件转移指令(它们检测zf、cf的值)
指令 | 含义 | 检测的相关标志位 |
---|---|---|
je | 等于则转移 | zf = 1 |
jne | 不等于则转移 | zf = 0 |
jb | 低于则转移 | cf = 1 |
jnb | 不低于则转移 | cf = 0 |
ja | 高于则转移 | cf = 0 且 zf = 0 |
jna | 不高于则转移 | cf = 1 或 zf = 1 |
j:jump,e:equal,b:below,a:above,n:not
这些条件转移指令通常和cmp指令配合使用的,根据cmp指令导致的寄存器变化结果进行条件转移。
但它们也可以不和cmp指令一起使用,那就看当前标志寄存器的状态。
1 | ;编程,统计data段中数值为8的字节的个数,用ax保存统计结果。 |
0x34:DF标志和串传送指令
方向标志位。在串处理指令中,控制每次操作后si、di的增减。
- df = 0每次操作后si、di递增;
- df = 1每次操作后si、di递减。
串传送指令:
格式:movsb
功能:将ds:si指向的内存单元中的字节送入es:di中,然后根据标志寄存器df位的值,将si和di递增1或递减1。
格式:movsw
功能:将ds:si指向的内存字单元中的字送入es:di中,然后根据标志寄存器df位的值,将si和di递增2或递减2。
格式:rep movsb
movsb和movsw进行的是串传送操作中的一个步骤,一般来说,movsb和movsw都和rep配合使用,
功能:rep的作用是根据cx的值,重复执行后面的串传送指令。
1 | rep movsb <==> s:movsb |
8086CPU提供下面两条指令对df位进行设置。
cld
指令:将标志寄存器的df位置0,正向复制std
指令:将标志寄存器的df位置1,反向复制
显然串传送指令很适合一段连续空间的复制操作。
1 | ;将data段中的第一个字符串复制到它后面的空间中。 |
0x35:pushf和popf
pushf的功能是将标志寄存器的值压栈,而popf是从栈中弹出数据,送入标志寄存器中
pushf和popf,为直接访问标志寄存器提供了一种方法。
标志寄存器在debug中的表示: