dosbox里运行debug.exe程序,显示的8位标志寄存器信息如下:
OF | DF | IF | SF | ZF | AF | PF | CF |
---|---|---|---|---|---|---|---|
OV | DN | EI | NG | ZR | AC | PE | CY |
NV | UP | DI | PL | NZ | NA | PO | NC |
一 | 向 | 短 | 福 | 零 | 富 | 偶 | 进 |
最后一行是为了方便记忆,加的一些谐音。自己想的,网上你们有更好的记忆方法么?可以留言分享啊,谢谢啦
源代码来自王老师课本P218页的举例。总结几句话为:
如果寄存器里算术运算视为无符号运算,未发生溢出结果正确,则CF = NC,如果还是发生了溢出,则CF = CY。
如果寄存器里算术运算视为有符号运算,不管是否发生溢出只要结果正确,则OF = NO ,如果结果不正确肯定是有溢出的,则OF = OV。因为电脑采用补码存储数据,在有溢出存在进位或借位的情况下,寄存器里结果仍然可以是正确的。这就是采用补码运算的神奇之处。如下面第三个例子。8086CPU在进行补码有符号运算时,不会一股脑一概而论的只要有溢出就OV,它还会自己检验结果的正确性,真神奇,但只有这么理解,才符合实验结果。欢迎高手专家来解惑。
(1)分析第一个结果:
98 = 62H , 99 = 63H ,98+99 = C5H = -59(有符号一个字节整数) = 197 (无符号一个字节整数)。
可见,有符号运算发生溢出,所以OF = 1,CF = 0
(2)
F0H = -16,88H = -120 ;F0H + 88H = 178H (进位1在单字节有符号运算里被舍弃); 而78H = 120 ,实际上
-16 + (-120) = -136 超过了-128,无法用一个字节表示。无符号运算一样发生了溢出导致无符号运算结果也不正确,所以CF = CY , OF = OV
(举例3)
F0H = -16,78H = 120;F0H + 78H = 168H ,68H = 104 = -16 + 120 可见,虽然有符号运算发生了进位溢出,但结果仍然是正确的。无符号运算当然是溢出了,但8086CPU仍然通过FR寄存器反馈给了我们非常智能化的准确的运算结果,显然,我们确实需要CPU给我们反馈正确的结果,至于CPU里的计算过程是次要的,神秘的。欢迎高手专家来解惑。
书上的文字迷惑了我几天,直到动手实验,才得到了真理。
【段落二 符号位SF】
经上机实验,可以认为SF位等价于CPU执行有符号算术运算时结果的符号位(al + bl ,返回al 的符号,ax + bx ,返回ax的符号,al X bl ,结果在ax中保存,仍返回al 段的符号,很奇怪,但实验结果如此。但cmp运算是减法运算,不是乘法运算)。当然存在运算结果溢出的情况,导致SF位不能真正准确的反应结果的正负性。
代码如下:
(实验一)
78H = 120,有意通过加法运算造成溢出,可见SF把AL当成有符号单字节数,取第7位(符号位,最高位)的值
(实验二)
进行乘法运算12 x 12 = 144;保存在ax里,未造成溢出,但SF = NG ,仍然给出的是AL段的符号,此时无意义
(实验三)
操作数是双字节的ax,最高位是第15位,SF与第15位保持一致
(实验4)
同上,当第15位变成1时候,SF = NG
【段落三 测试cmp指令】
我们接着学习cmp指令,只有真正弄清楚cmp指令对FR(flag register)的影响,我们才可以放心的在程序中使用cmp指令。
cmp ax,bx 相当于(ax) = (ax) - (bx)。标志位反应的也是运算后ax的数据信息。但实际上cpu并不修改ax寄存器的值。
总结cmp 指令:8086CPU计算(ax)- (bx)的结果,按无符号运算的结果,修正CF和ZF的值。按有符号数运算的结果,修正OF与SF和ZF的值。至于采用哪种运算逻辑,取决于程序员本人的数据运算需求。
测试代码入下(冒号后为注释,不知道汇编代码该选哪个类型):
assume cs:code
code segment
main:
mov al,78H;78H = 120
cmp al,0fdh;FDh = -3
cmp al,78h;考虑下等于ZF
mov al,7bh;7b = 123
cmp al,0FBh;FBh = -5
mov al,85h;85h = -123
cmp al,5;-128未溢出
mov al,85h
cmp al,6
mov ax,4c00h
int 21h
code ends
end main
(实验一)
78H - FDH = 120 - (-3)= 123 = 7BH,无符号运算有借位;有符号运算有借位,但结果正确,无溢出,符号位为0.故寄存器FR取值一次为NV PL NZ CY。此情况对应有符号运算的正数减较小负数仍未溢出的情况
第二个比较78H = 78H,故 取值 ZR
(实验二)
7BH - FBH = 123 - (-5)= 128 = 80H 有借位、溢出,且有符号运算结果不正确、非零,符号位为1。故 OV NG NZ CY
此对应较大正数减去较大负数造成有符号运算溢出的情况
(实验三)
85H - 05H = -123 - 5 = -128 = 80H 无符号运算未借位,有符号运算正确,未溢出,符号位为1,非0:NV NG NZ NC
此对应有符号运算负数减较小正数未溢出的情况
(实验4)
85H - 06H = -123 - 6 =-129?溢出;但85H - 06H = 7FH = 127 。无符号运算未借位,有符号运算未借位但溢出,结果错误,非0 符号位为0:OV PL NZ NC
此对应有符号运算较大负数减较大正数溢出的情况
综上,运用cmp指令后,无符号运算看CF,有符号运算看OF 与 SF 即可准确判断 比较的两个数的大小情况
谢谢阅读,指正