对汇编补码计算加法转减法计算的疑问

xjwplx 2009-06-02 09:43:11
汇编中OF=1表示带符号的运算结果无效,CF=1无符号的运算结果无效。

对加法容易理解。但是对减法我理解不了:
0100,0001b-1010,1011b

(1)直接用减法计算:
//debug
0BAD:0005 B041 MOV AL,41
0BAD:0007 2CAB SUB AL,AB
-t
AX=0B96 BX=0000 CX=001D DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0BAC ES=0B9C SS=0BAC CS=0BAD IP=0009 OV UP EI NG NZ AC PE CY
0BAD:0009 B409 MOV AH,09
结果OF =1,CF=1,所有有符号和无符号都无效。

(2)利用[X-Y]补 = [X]补 + [Y]补
上面的式子等价于:
0100,0001b+0101,0101b
//debug
0BAD:0005 B041 MOV AL,41
0BAD:0007 0455 ADD AL,55
-t
AX=0B96 BX=0000 CX=001D DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0BAC ES=0B9C SS=0BAC CS=0BAD IP=0009 OV UP EI NG NZ NA PE NC
0BAD:0009 B409 MOV AH,09
结果OF=1,CF=0,所以有符号计算无效,无符号计算有效。

上面的例子两种方法计算的得出的结论怎么不同?
...全文
779 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
YiYanXiYin 2012-07-07
  • 打赏
  • 举报
回复
凭什么说
0100,0001b-1010,1011b 和 0100,0001b+0101,0101b 相等
YiYanXiYin 2012-07-07
  • 打赏
  • 举报
回复
楼主将加法转成减法的理论从哪里来的?肯定有问题
goodider 2009-06-03
  • 打赏
  • 举报
回复
上面的图要数位对齐。打字的时候是齐的。结果显示出来没对齐。要注意
goodider 2009-06-03
  • 打赏
  • 举报
回复
加法与减法影响的标志
加法和进位标志:如果分别考虑加法和减法两种情况,对进位标志的操作是容易理解的。两个无符号整数相加,进位标志的值就是运算结果最高有效位向高位的进位值。直观的看,当相加之和超过了目的操作数的大小时CF等于1。
例子:
mov al,0FFh
add al,1 ; AL=00,CF=1
图示

进位 1 <-|
1 1 1 1 1 1 1 1 0FF
+ 0 0 0 0 0 0 0 1 1
-------------------------------------------------------
0 0 0 0 0 0 0 0
图中用数据位的层次显示了当OFFh加1时候发生了什么,其中AL的最高有效位向高位的进位值被复制到进位标志中。

另一方面如果我们向AX中的00FFh加1的话,之和便可以放置于16位的值中。相应的进位标志被清零
例:
mov ax,00FFh
add ax,1 ;AX=0100h,CF=0

如果AX寄存器中的是FFFFh加1,那么AX的最高位就会产生进位
例:
mov ax 0FFFFh
add ax,1 ; AX=0000h,CF=1


减法和进位标志:在进行减法运算时,如果一个较小的无符号整数减去一个较大的无符号整数,进位标志会被置位。从硬件的角度考虑减法对进位标志的影响是最容易理解的。假设某一时刻,CPU能对一个无符号正整数求补得到其反数:
1. 对源操作数(减数)求反再与目的操作数(被减数)相加。
2. 最高有效位的进位值反转(求反)后复制到进位标志中。
例子:
我们以1减2为例。假设操作数是8位的,在对2求反后,把两个整数相加。
如图:


0 <-|
0 0 0 0 0 0 0 0 1
+ 1 1 1 1 1 1 1 0 -2
----------------------------------
1 1 1 1 1 1 1 1
如果把和(255)看做是有符号整数,那么结果实际上就是有符号数-1,运算结果是对的。
上图对应的汇编代码如下:
mov al,1
sub al,2 ; AL=FFh,CF=1

另外,INC和DEC指令补影响进位标志,对非零操作数执行NEG操作则总是设置进位标志。

有符号运算:符号和溢出标志
符号标志:有符号算数运算的结果为负时,符号标志职位。
例子: 4-5
mov eax,4
sub eax,5 ; eax=-1,sf=1
符号标志就是运算结果最高位(被舍弃)的副本。

溢出标志:有符号运算结果上溢(太大)或下溢(太小)以至目的操作数无法容纳时,溢出标志职位。
例:
一个字节最大存储有符号整数是+127。此时加1将上溢(太大)
mov al,+127
add al,1 ;OF=1
一个字节能容纳的最小负整数是-128如果再减1将导致下溢(太小)
mov al,-128
sub al.1 ;OF=1

在两个有符号整数相加时,有种简单的方法判断是否溢出。
如果出现如下情况将溢出:
1 两个正数相加之和是负数
2 两个负数相加之和是整数

但两个加数的符号不同时,永远不会发生溢出。

array020 2009-06-02
  • 打赏
  • 举报
回复
计算机可不管你想干什么,它只是忠实的记录已经发生的一些计算的客观事实。
xjwplx 2009-06-02
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 damacheng 的回复:]
哎。。照你的意图
第一个是有符号运算
第二个是无符号运算
结果OF不一样,就是不一样了。
[/Quote]

不是这样的,我只是对第一种方法(直接使用sub指令)的结果进行有符号和无符号分析。
array020 2009-06-02
  • 打赏
  • 举报
回复
我想是你想当然了,你认为两种方法得出的结果一样,那么标志寄存器的值就是一样的 可计算机不那么认为
一个ADD,另一个是SUB,是两个指令,运算后OF的值当然有可能不一样。
xjwplx 2009-06-02
  • 打赏
  • 举报
回复
汇编中的加减运算应该是不区分有符号和无符号的,所以先不谈有符号和无符号结果正不正确的问题。

我只是将一个运算实例:
0100,0001b-1010,1011b
用两种方法去实现它. 一种是指直接使用汇编的减法指令sub. 一种是使用补码运算规则:
[ X-Y ]补 = [X]补 + [Y]补
去实现.但是求出的状态值不一样
array020 2009-06-02
  • 打赏
  • 举报
回复
哎。。照你的意图
第一个是有符号运算
第二个是无符号运算
结果OF不一样,就是不一样了。
array020 2009-06-02
  • 打赏
  • 举报
回复
额。。。应该是-171.。搞成-176,应该是-85搞成-95.。。。

改正。。。

(1)假设有符号:65-171=-106 <0,借位,假设无符号65-(-85)=150>127,溢出
(2)假设有符号:65+85=150,无借位,假设无符号65+85=150>127,溢出
xjwplx 2009-06-02
  • 打赏
  • 举报
回复
这样算溢出与超出范围我知道,但是汇编教科书上指明了

汇编中OF=1表示有符号的运算结果超出有符号表示范围,结果无效,CF=1表示无符号的运算溢出,结果无效。

我上面的例子通过两种方法计算补码的减法,一种是利用汇编的sub指令,一种是利用补码的运算规则转化为加法操作。最终求出的值是一样的,但是标志位不同:
直接减法是: OV UP EI NG NZ AC PE CY <---CF=1,OF=1
装化为加法是: OV UP EI NG NZ NA PE NC <---CF=0,OF=1
这是为什么?
xjwplx 2009-06-02
  • 打赏
  • 举报
回复
不明白,对于减法计算应该是
(1)假设是无符号数,运算是:
65 - (-85)
计算机运算结果为-105[1001,0110B],结果无效
假设无符号数,运算是:
65 - 171
计算机运算结果为150[1001,0110B],有借位,结果无效
array020 2009-06-02
  • 打赏
  • 举报
回复
(1)假设有符号:65-176=-116<0,借位,假设无符号65-(-95)=160>127,溢出
(2)假设有符号:65+95=160,无借位,假设无符号65+95>127,溢出

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧