在汇编语言中,标志位是很重要的东西,我们查看标志位可以很好的了解当前指令操作带来的变化,那么我们应该怎样来查看标志位呢?
在debug中每次执行过相关指令后在右下角可以看到一些两位英文大写字母,这就是标志位,从左向右依次为:
有符号溢出标志位OF(Over flow flag) OV(1) NV(0)
方向标志位DF(Direction flag) DN(1) UP(0)
中断标志位IF(Interrupt flag) EI(1) DI(0)
符号标志位SF(Sign flag) NG(1) PL(0)
零标志位ZF(Zero flag) ZR(1) NZ(0)
辅助进位标志位AF(Auxiliary carry flag) AC(1) NA(0)
奇偶标志位PF(Parity flag) PE(1) PO(0)
无符号进位标志位CF(Carry flag) CY(1) NC(0)
后面括号里的0/1指的是标志位相关状态,为0则代表次标志位没有变化,为1则代表这次执行指令产生了变化。
如在如下debug中的测试(debug安装使用在这里----->戳我!)这个debug安装指南非常简洁,推荐:
**1.**第一个r指令是查看当前各寄存器的状态,并未执行相关指令,可以看到右下角的各个标志位并未发生变化
**2.**输入t指令,执行之前设置好的乘法指令:mul ax,bx 即将ax与bx相乘再将结果存放与ax中,我们可以发现右下角的溢出标志位OF由NV变为OV,OV是“1”,即说明发生了溢出,ax只有16位即两个字节,ax与bx的积在ax中放不下,发生了溢出,溢出部分存放在了dx当中。再看进位标志位CF,从NC变成了CY,表明发生了进位。
**3.**执行下一条指令(第二个t):在执行add cx,dx 之后,我们发现溢出标志位回复了正常,进位标志位也回复了正常,但是奇偶标志位发生了变化,PE说明发生了积偶的变化。
其他的积偶标志位也会随着相关的操作而产生变化,下面做一点下总结:
一:数据交换类指令不会引起标志位的变化。
二:数据传送类指令不会引起标志位的变化。
三:算数运算类指令会影响标志位变化:
(1):加法类指令中add,adc会影响CF,ZF,PF,OF,AF,SF等标志位的变化。但是加法指令里的自增指令INC在上述标志位中不会影响cf(无符号进位标志)的变化;那么,或许有人会说,cf进位标志,我对一个寄存器自增到要进位的时候,不是会发生进位标志的改变吗?请看:
让ax等于FFFF,即最大的值的时候,再执行自增的操作,会发现,进位标志CF并未发生变化,反而是零标志ZF,辅助标志AF以及积偶标志PF发生了变化,这就说明在临界情况下自增会成为零(循环变化)对别的通用寄存器也没有产生影响(没有把ax寄存器的值存在别的寄存器里,只是发生了清零效果)!
(2)在减法类指令中,sub,sbb,neg(求补指令),cmp(比较指令)指令会影响全部的标志位,但是自减指令dec不会影响cf(进位借位标志位)。
和加法一样,减法也是对寄存器进行循环的处理,ax 0000自减后会变成ffff,并未引起cf标志位的变化。
(3)乘法指令只对of、cf标志位造成影响,对其他的标志位的影响不确定(无定义)。
(4)除法对标志位没有影响·。
四:逻辑类指令:
图片指令执行从上向下依次为与(and),或(or),异或(xor),ax,bx,cx初始值都为1010。
第一次进行逻辑与或异或,并未得到结果。
第二次分开设置特殊数据查看:已下是先对ax进行乘法运算,再进行与(and)运算,多次实验发现ax执行与运算会使得标志位of、cf置零
已下是对ax先乘法运算再或运算(or),同样发现只会使得标志位cf、of进行置零操作。
多次对xor异或操作进行运算也是如此,所以得出结论:(1)对寄存器进行逻辑运算,每次都会使得of、cf标志位清零。
(2)也会引起pf奇偶标致位的变化
简介逻辑移动及算数移动:(1)左移:逻辑左移和算数左移一样,符号位进入cf进位标志位保存,其他位整体左移,末尾补零; (2)右移:逻辑右移和左移一样,只是换了个放向。但是算数右移则有些不同,算数右移尾部不断进入cf标志位保存,但是头部不会补零,而是符号位在不断的重复,如图。这是一个特例。
标志位变化:
第一个命令(t)时我们使得of/cf位发生变化;’第二个命令(t)是对ax发生逻辑左移,我们发现cf、of位发生了变化;第三个命令(t)是对bx发生逻辑右移,我们发现cf、of位都恢复了正常;第四个命令(t)是最cx进行算数右移,cf、of标志位又发生了变化。
多次实验我发现,每次我们进行移动的过程中进入cf标志位保存的数是使得cf变化的原因,of和af相应根据数的变化发生变化`,of=1 ,移动后最高位的值发生变化;of=0 ,移动时最高位的值未发生变化。
2.循环移动
对循环移动的简介:
(1)不带进位的循环移动,每次左循环移动之后,在符号位的数进入cf标志位保存;每次循环右移后,在末尾的那个数进入标志位保存。
例:有个数10010010,现在进行不带进位标志的循环左移,移动一次后成为00100101,而cf变成0;再进行不带进位的循环右移,又变成10010010,cf置换为1。
(2)带进位循环移动和逻辑算数移动不同的地方在于循环移动每次移动加入了cf标志位,cf标志位是本来存在的,每次移动带上标志位一起移动,比如8位就变成了9位,16位变成了17位。
举例:比如一个8 位数 81H,二进制的就是1000 0001,假设最初的进位标志位CF为0 。带进位循环左移后,81H的最高位移入进位标志位,此时,进位标志位CF为1,数为0000 0010 。再左移一次,进位标志位的1移到最低位,此时,进位标志位为0,数为0000 0101 。带进位循环右移的话,数为0100 0000,进位位C为1,再移一次,则进位位移入最高位,进位位变成0 ,数为1010 0000
对于标志位变化,和逻辑移动算数移动一样,也是cf保存的值影响cf,of判断数据头是否发生溢出变化,pf判断数奇偶变化!