|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 奥普瓯江 于 2018-12-27 18:14 编辑
- CF OF SF ZF PF
- 1. sub al, al NC NV PL ZR PE
- 2. mov al, 10h NC NV PL ZR PE
- 3. add al, 90h NC NV PL NZ PE
- 4. mov al, 80h NC NV PL NZ PE
- 5. add al, 80h CY OV PL ZR PE
- 6. add al, 0fch CY OV PL ZR PE
- 7. add al, 05h CY NV PL NZ PO
- 8. mov al, 7dh CY NV PL NZ PO
- 9. add al, 0bh NC OV NG NZ PE
复制代码
这里面有个疑问地7行和第8行
在第六行中al被赋予了FC16进制的,换算程2进制的话应该是1111 1100,第7行中的add al, 05h中05换算成2进制应该是0000 0101这就相当于:
1111 1100加上0000 0101他应该等于1 0000 0001,在这里产生了溢出符号位改变了但是OF显示的是NV(NV代表没有溢出)为什么呢?,
本帖最后由 行客 于 2018-12-27 23:51 编辑
以下是我用了将近2个小时,本着以最直白的语言,弄到将近深夜12点才写完的材料,希望你能认真看,认真理解。因为这里我不只是解释了你上面的问题,而是从根本上帮助你进行理解:
计算机数值一律用补码来表示(存储)。0xFC(即上面的0fch)在al中,表示为补码,是负数,即-4;0x5(即上面的05h)是正数5。所以add后结果为1。你可以看一下执行完第7行后al是0x1(EAX显示为FFFFFF01)。
如果还有疑问,你可以测试一下以下三条指令:
SUB AL, AL
MOV AL,0FFh
MOV AL,02h
执行完后看一下al结果和标志位。
我再详细给你一下,你之所以会提出这个问题,是因为你对CF和OF没有区分开:
CF为进位标志(Carry Flag),OF为溢出标志(Overflow Flag)。
我们通常理解的溢出是,我们假设有一个杯子,然后向杯子倒水,如果水满了,这就是溢出了。那么这个杯子到底有多大?按照你上面的理解,你会不会觉得OF和CF没什么区别?其实,这里面涉及到杯子真实大小的问题。
不过,真实的情况是,虽然,我们通常认为溢出(上溢),认为就是因为进位时当前存储格式(1B、2B、4B等)的位数(8bit、16bit、32bit)不够而引起的。比如8位寄存器:11111111B+1B=100000000B超过了八位的1被认为是溢出寄存器(放不下),当然这里也是进位进上去的1。但是实际上,CF标志位的进位标志与OF标志位的溢出标志是不同的概念。
那么好,为了好理解,接下来我们假设寄存器为8位寄存器(al)。
首先,你要理解,CF针对的是无符号数运算(将寄存器中的操作数都看作是无符号数) ;OF针对有符号数运算(将寄存器中的操作数都看作是有符号数) 。有符号无符号指的是最高位是否(注意,我这里说的是“是否”)是符号位,即我们是是以原码的形式(即无符号数,或者说就是正数)看待这个操作数还是以补码的形式(有符号数,有正数也有负数)看待这个操作数。
你要记清楚,CF看的是无符号运算(原码),OF看的是有符号运算(补码)。
如果以原码的形式看待操作数,也就是从CF角度去看,那么这个数的范围是00h~FFh,也就是十进制0~255(注意,计算机中的无符号数(所谓的正数)包含0)。
如果以补码的形式看待操作数,也就是从OF角度去看,那么这个数的范围80h~7Fh,也就是十进制-128~127。注意,80h~FF等同于-128~-1;0~7F等同于0~127。
这就是杯子的真实大小。
我再补充一句,加强你的理解:一个操作数在寄存器或内存中,这个数是无符号数还是有符号数,不是这个数或者是计算机决定的,而是我们程序员来决定的。所以,到底溢出不溢出,如果我们把这个数要看成无符号数,那么我们就要去看CF;如果看成有符号数,那么就要去看OF。
所以,我们的结论来了
CF和OF其监测的结果数据范围是不同的:
以8位寄存器作为操作种数据来源为例,如果一个运算的结果最终超过[-128,127]无论是大于127还是小于-128就被认为是溢出,OF被置为1,如果结果在[-128,127]就认为没溢出OF被置为0,。
而对于OF:如果计算的结果超过[0,255]的范围,就有进位,CF就被置为1,如果结果再[-128,127]范围内,就是没有进位CF被置为0。
说到这里你应该明白了。为了继续加强你的理解,我再举几个例子:
(1)、8H+8H:
对于signed(有符号数):(8)+(8)=16,没超过[-128,127]的范围,OF为0
对于unsigned(无符号数):(8)+(8)=16,没超过[0,255]的范围,CF为0
(2)、80H+81H:
对于signed:(-128)+(-127)=-255,超过[-128,127]的范围,OF为1
对于unsigned:(128)+(129)=257,超过[0,255]的范围,CF为1
(3)、FCH+05H:
对于signed:(-4)+(5)=1,没有超过[-128,127]的范围,OF为0
对于unsigned:(252)+(5)=257,超过[0,255]的范围,CF为1
(4)、7FH+2H:
对于signed:(127)+(2)=129,超过[-128,127]的范围,OF为1
对于unsigned:(127)+(2)=129,没超过[0,255]的范围,CF为0
你一定要记住,操作数看成有符号还是无符号,不是计算机决定的,是你作为程序开发人员决定的。所以,如果你认为这个数是无符号数,那么你就看CF,不用理会OF;如果你人为这个数是有符号数,那么你就看OF,不用理会CF。OF、CF的0与1是没有直接联系的。只要记住有符号与无符号的数据范围,并且记住OF是对于有符号数,CF对于无符号数即可。
|
|