Joh*_*ang 5 assembly unsigned subtraction
假设A
和B
是带正号的正整数,则对于A-B
,它是使用A+2
的的补码计算的B
。
例如,在4位二进制系统中,对于有符号整数,我们有
7-3=0111-0011=0111+1101=(1)0100
,括号中的1是进位位。根据有符号整数的溢出规则,我们知道没有溢出,因此结果是正确的。
但是,对于无符号整数,如果我们计算会发生什么7-3
?如果我们使用上面提到的相同方法:
7-3=0111-0011=0111+1101=(1)0100
Run Code Online (Sandbox Code Playgroud)
然后,根据无符号整数的溢出规则,由于进位而导致溢出。换句话说,这0100
是错误的,因为存在溢出。但实际上,我们知道结果0100
是正确的。
如果我的分析是正确的,那么使用加法器执行无符号整数减法是不是错误?
您的分析不正确。实际上是取决于CPU ALU单位的。:)
在第一种情况下,您使用的是4位整数,但您忘记了4位符号整数的最高位是sign!因此,您只检查进位和溢出状态,而不要检查负状态位。
在通常的二进制算术运算中,有符号整数和无符号整数的add和sub相同。只有受影响的标志是不同的。
实际上,您必须考虑:
详细说明:
补数函数的挖掘是否定的,因此从正得到相反的负数,从负得到正的值。我们可以通过两种方式进行二进制补码。让我们看一下数字3的两种情况。
在第一种情况下,函数补码也对进位位进行补码,我们还对进位标志的第二种解释命名为借位。
在第二种情况下,一切都清楚了。如果我们在进位有进位(溢出),这意味着我们需要另一个溢出来标准化减法结果。
在这个相关问题的答案中,有 C 语言的示例代码,展示了如何通过加法进行减法。该代码还设置进位和溢出标志,并包含一个简单的“测试”,用于添加和减去一些数字并打印结果。这些数字是 8 位的。
编辑:正式证明可以使用 ADD 而不是 SUB 来处理无符号整数,并且可以像从 SUB 中一样发现无符号上溢/下溢。
假设我们要计算a - b
,其中a
和是 4 位无符号整数,并且我们希望通过加法执行减法,并在a < bb
时获得 4 位差值和下溢/上溢指示。
a - b = a + (-b)
由于我们使用模 16 算术运算,所以-b
= 16-b
。所以,
a - b = a + (-b) = a + (16 - b)
如果我们执行常规无符号加法,a
并且16-b
该加法的溢出条件(通常由 CPU 在其carry
标志中指示)将是这样的(回想一下,我们正在处理 4 位整数):
a + (16 - b) > 15
让我们简化这个溢出条件:
a + 16 - b > 15
a + 16 > 15 + b
a + 1 > b
a > b - 1
现在让我们回想一下我们正在处理整数。因此上面可以重写为:
a >= b。这就是与相加
后进位标志 = 1 的条件。如果不等式不成立,我们得到进位 = 0。a
(16)-b
现在让我们回想一下,我们对减法 (a - b) 的上溢/下溢感兴趣。该条件是a < b。
嗯,a >= b与a < b完全相反。
由此可见,通过加法和carry
得到的标志是减法溢出的倒数,或者换句话说,是通过使用适当的减法指令(例如 SUB)直接减去得到的标志的倒数。a
(16)-b
borrow
b
a
只需颠倒进位或以相反的方式处理即可。