标志寄存器一点细节
- MD DoOCuMenT:3/4/2016 2:43:28 PM by Jimbowhy
- CSDN PuBliShEd:http://blog.csdn.net/WinsenJiansbomber/article/details/50802609
开始接触汇编时,一个比较容易混淆的问题就是关于标志寄存器的进位和溢出。特别是先入为主地认为运算结果超过寄存器的数值表达范围时就是溢出,这是不对的,这很有可能只是高位进步而不是溢出,列如两个-1相加的情况就是,后面结合负数的补码来分析。一个典型的CPU上,标志寄存器应该有以下这几个状态位,其值对应不同的意义:
Flag Name =1 =0
CF Carry Flag CY/Carry NC/No Carry
PF Parity Flag PE/Parity Even PO/Parity Odd
AF Auxiliary Carry AC/Auxiliary Carry NA/No Auxiliary Carry
ZF Zero Flag ZR/Zero NZ/Not Zero
SF Sign Flag NG/Negative PL/Positive
TF Trace Flag
IF Interrupt Flag EI/Enable Interrupt DI/Disable Interrupt
DF Direction Flag DN/Down UP
OF Overflow Flag OV/Overflow NV/Not Overflow
进位标志 CF
用于反映运算是否产生进位或借位。如果运算结果的最高位产生一个进位或借位,则CF置1,否则置0。运算结果的最高位包括字操作的第15位和字节操作的第7位。移位指令也会将操作数的最高位或最低位移入CF。
奇偶标志PF
用于反映运算结果低8位中“1”的个数,偶数时则PF置1,否则置0。
辅助进位标志 AF
在字节操作时低半字节向高半字节进位或借位,字操作时低字节向高字节进位或借位,AF置1,否则置0。
零标志 PF
用于判断结果是否为0。运算结果0,ZF置1,否则置0。
符号标志 SF
用于反映运算结果的符号,运算结果为负,SF置1,否则置0。因为有符号数采用补码的形式表示,所以SF与运算结果的最高位相同。
溢出标志 OF
反映有符号数加减运算是否溢出。如果运算结果超过了8位或者16位有符号数的表示范围,则OF置1,否则置0。
跟踪标志 TF
控制标志,当TF被设置位1时,CPU进入单步模式,所谓单步模式就是CPU在每执行一步指令后都产生一个单步中断。主要用于程序的调试。8086/8088中没有专门用来置位和清零TF的命令,需要用其他办法。
中断标志 IF
决定CPU是否响应外部可屏蔽中断请求。IF为1时,CPU允许响应外部的可屏蔽中断请求。
方向标志 DF
决定串操作指令执行时有关指针寄存器调整方向。当DF为1时,串操作指令按递减方式改变有关存储器指针值,每次操作后使SI、DI递减。
结合汇编的分析
先要了解负数的补码表达,有一个方法来解析负数的补码是什么。设想一个展馆,每天到访客流都有个限额,假设最大的额度就是255,刚好是一个字节可以存储的最大值。那么每有一个访客额度就会减一,即表示负一:
1111 1111 - 1 = 1111 1110
这种方法也就是用0来表达1,用1来表达0的反转计数方法。实际上使用的补码是2’补码,即在1’补码的基础上加一,也就是取反加一的补码形式,这样计算机可以用加法器就可以进行减法运算。
首先,在x86平台上,通过Intel可以查询到 mov 指令不影响任何标志位,所以执行它时,标志寄存器的状态不改变。而 add 指令会影响 AF, CF, OF, PF, SF, 和 ZF。 注意32-bit的-1补码即是0xFFFFFFFF,-2补码即是0xFFFFFFFE,0x7FFFFFFF 表示 int 数据的最在正数。
CPU Disasm
Address Hex dump Command Comment
12A4 B0 80 mov al,80
12A6 B2 80 mov dl,80
12A8 00D0 add al,dl 8-bit运算,有进位到ah,溢出,因为结果256不在表达范围;
AF=0, CF=1, OF=1, PF=1, SF=0, ZF=1
12AA B8 FFFFFFFF mov eax,-1
12AF BA FFFFFFFF mov edx,-1
12B4 01D0 add eax,edx 16-bit运算,最高位有进位但不是溢出,因为结果-2在表达范围;
AF=1, CF=1, OF=0, PF=0, SF=1, ZF=0
12B6 B8 FFFFFF7F mov eax,7FFFFFFF
12BB BA FFFFFF7F mov edx,7FFFFFFF
12C0 01D0 add eax,edx 16-bit运算,无有进位但是溢出,因为两个正数相加结果变成-2;
AF=1, CF=0, OF=1, PF=0, SF=1, ZF=0
12C2 B0 7F mov al,7F
12C4 B2 7F mov dl,7F
12C6 00D0 add al,dl 8-bit运算,
AF=1, CF=0, OF=1, PF=0, SF=1, ZF=0
参考资源
- Intel 80386 Reference Programmer’s Manual