溢出与进位
对于无符号数来说,不存在溢出的问题,它的进位就相当于有符号数中的溢出
而对有符号数来说,不存在进位的问题
一个字节(8位) 的数有256个 (2的8次方)
一个字(16位) 的数有65536个 (2的16次方)
8个二进制位能够表达的无符号数范围是:0 ~ 255
16位表达的无符号数范围是:0 ~ 65535
对于无符号数来说,不存在溢出的问题,它的进位就相当于有符号数中的溢出.
进位表示最高位有没有向上形成进位,或向个形成借位,如果有则进位标志CF为进/借位数,但结果没错。
进/借位数要看 十六进制、二进制,进/借的是十六进制、二进制的最高位处理器内部以补码表示有符号数,
8个二进制位能够表达的有符号数范围是:+127 ~ -128
16位表达的有符号数范围是:+32767 ~ -32768
如果运算结果超出了这个范围,就是产生了溢出,有溢出,说明有符号数的运算结果不正确
溢出是指结束超出数据所表示的范围,通俗地说是装不下了,比如,两个带符号的字节数127和2相加,结果为-1,因为带符号的字节数最大正数为127,所以超过范围,溢出标志位OF为1,说明出错了。
对于有符号数来说,不存在进位的问题
例如:
3AH + 7CH=B6H,就是58 + 124=182,已经超出-128 ~ 127范围,产生溢出,所以OF=1;另一方面,补码B6H表达真值是-74,显然运算结果也不正确。
溢出标志OF和进位标志CF是两个意义不同的标志.
n 进位标志表示无符号数运算结果是否超出范围,运算结果仍然正确;
n 溢出标志表示有符号数运算结果是否超出范围,运算结果已经不正确。
请看例子
例1:3AH + 7CH=B6H
无符号数运算:58+124=182,范围内,无进位
有符号数运算: 58+124=182 ,范围外,有溢出
例2:AAH + 7CH=(1)26H
无符号数运算:170+124=294,范围外,有进位
有符号数运算:-86+124=28 ,范围内,无溢出
处理器对两个操作数进行运算时,按照无符号数求得结果,并相应设置进位标志CF;同时,根据是否超出有符号数的范围设置溢出标志OF。
应该利用哪个标志,则由程序员来决定。也就是说,如果将参加运算的操作数认为是无符号数,就应该关心进位;认为是有符号数,则要注意是否溢出。
判断运算结果是否溢出有一个简单的规则:只有当两个相同符号数相加,而运算结果的符号与原数据符号相反时,产生溢出,此时的运算结果显然不正确。其他情况下,则不会产生溢出。
两个正数相加(或一个正数减一个负数)得到负数,或是两个负数相加得到正数,就是溢出了.
一个正数和一个负数相加不可能溢出
|
|
进位与溢出
进位与溢出
Cy位是进位位,用来表示本次无符号数运算结果的溢出。由于无符号数的最高有效位只有数位意义而无符号意义,所以该位所产生的进位应该是本次运算结果的实际进位值。所以说:进位位Cy是在给定二进制数的位数范围内,代表了本次运算结果的溢出情况。另一方面,它所保存的进位值有时也是有用的。例如,双字长运算时,可以利用进位值把低位字的进位计入高位字。
OV位表示溢出。溢出位是用来表示带符号数的运算结果超出有限字长的表示范围的标志。它是根据两个操作数的符号及其变化来设置的。如两个操作数符号相同而运算结果的符号与之相反时OV=1,反之,OV=0。
例题1:无符号数和带符号数均不溢出
|
|
按无符号数对待 |
按带符号数对待 |
| 0000 0100 |
4 |
(+) 4 |
| + 0000 1011 |
+ 11 |
+ (+)11 |
| 0000 1111 |
15 |
(+)15 |
例题2:无符号数溢出的情况
|
|
按无符号数对待 |
按带符号数对待 |
| 0000 0111 |
7 |
(+)7 |
| + 1111 1011 |
+ 251 |
+ (-)5 |
| 1Cy 0000 0010 |
258 |
(+)2 |
|
|
Cy = 1 |
OV =0 |
注:在字长为8位的情况下,258表示的也是2,所以结果均为2。
例题3:带符号数溢出的情况
|
|
按无符号数对待 |
按带符号数对待 |
| 0000 1001 |
9 |
(+)9 |
| + 0111 1100 |
+ 124 |
+ (+)124 |
| 1000 0101 |
133 |
(+)133 |
|
|
Cy =0 |
OV = 1 |
例题3:带符号数和无符号数均溢出的情况
|
|
按无符号数对待 |
按带符号数对待 |
| 1000 0111 |
135 |
(-)121 |
| + 1111 0101 |
+ 245 |
+ (-)11 |
| 1Cy 0111 1100 |
380 |
(-)132 |
|
|
Cy =1 |
OV = 1 |
结论:两个同符号数相加,才可能产生溢出。两个符号相异的数相加不可能产生溢出。计算机对进位位的判断规则为:两个带符号数进行补码加减运算时,通常用符号位产生的进位(S代表)与最高有效数值位向符号位产生的进位(Cy代表)进行异或操作,若异或结果为1则发生溢出,反之则无溢出发生。OV = S + Cy 。以8位二进制为例,OV = Cy7 + Cy6 。
例题4:十六位数举例。
| 0100 0110 0101 0010 |
→ |
4652 |
| + 1111 0000 1111 0000 |
→ |
+ F0F0 |
| 1Cy 0011 0111 0100 0010 |
|
3742 |
|
|
Cy =1 OV = 0 |
|
| 1111 0011 0110 0101 |
→ |
F365 |
| + 1110 0000 0010 0100 |
→ |
+ E024 |
| 1Cy 1101 0011 1000 1001 |
|
3742 |
|
|
Cy =0 OV = 0 |
|
例题5 8位数举例。
| 0111 1000 |
→ |
120 |
| + 0110 0100 |
→ |
+ 100 |
| 1101 1100 |
|
220 |
| 1000 1000 |
→ |
136 |
| + 1001 1100 |
→ |
+ 156 |
| 1Cy 0010 0100 |
|
292(36) |
总结:无符号数 Cy =0 OV = 0
带符号数 Cy7 =0 Cy6 = 1 OV = 1
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
所谓符号扩展问题是指一个数从位数较少扩展到位数较多(如从8位扩展到16位,或从16位扩展到32位)时应该注意的问题。
有符号数是用最高位是0或1来标记正负的,如果最高位是0(如8位数中的第7位,从0位开始算的)表示正数,而是1表示负数。16位数中的第15位控制符号。符号数扩展实称为带符号扩展。只是位数的扩展,不能改变原值的!
如0000 1101这个数是带符号数为13,扩展为16位时,一个16位数也要是13的!而这个数是0000 0000 0000 1101就可以了!所以正数的带符号扩展前边是加0,这只是一个规律而不是本质,本质就是数大小不改变!
讯享网
而带符号数不是-13的!而是将其取补加1就是负数结果,即-0111 0010 + 1,结果就是-115,如果将这个带符号数扩展时,只有16位1111 1111 1000 1101才是-115,扩展只是表示范围大了,而不是改变数值的。如果是正数前8位是0,如果是负数,前8位是1,这样才是带符号扩展的。这不是本质,只是一个规律而已!
在汇编语言中,我们经常要对字/字节的数据进行操作。当把“字节”转换成“字”,或“字”转换成“双字”时,就需要进行符号扩展。符号扩展的具体操作就是把已知信息的最高位扩展到所有更高位。
例1.1 把8位补码0101 1010、分别扩展成16位补码。
解:根据符号扩展的含义,“字节→字”的具体扩展结果如下:
|
|
0101 1010 |
|
1010 1100 |
| 0000 0000 |
0101 1010 |
1111 1111 |
1010 1100 |

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/36068.html