我尝试比较以下表达式:
1)
mov al, 4
mov bl, 12
sub al, bl ; CF == 1
0000 0100 (4)
+
1111 0100 (-12)
=
1111 1000 (-8 == 248)
2)
mov al, 4
mov bl, -12
add al, bl ; CF == 0
0000 0100 (4)
+
1111 0100 (-12)
=
1111 1000 (-8 == 248)
结果相同,但进位标志不相同。为什么?通过加二进制补码值来实现减法。
减法不等于在x86上加两个补码。要了解进位标志将假定的值是什么,您必须执行长减法:
0000 0100
- 0000 1100
-------------
1 1111 1000
看看最后还有剩余的借款吗?借位是设置进位标志的位置(即进位等于借位)。
某些其他体系结构(例如ARM)的确确实实现了减法作为加法,但不是将两者的补码相加而是将一个人的补码与额外的进位相加。减法为0时非常重要。
例如,您的方法将得出12 − 0:
0000 1100
+ 0000 0000 (- 0000 0000 => + 0000 0000)
-------------
0 0000 1100
随身携带。但是实际发生的是
0000 1100
+ 1111 1111 (- 0000 0000 => +1111 1111 + 1)
+ 1
-------------
1 0000 1100
随身携带。此详细信息非常重要,否则与0的比较将无法正常进行。在此方案中,只要没有借入即表示进位(即,进位是补充借入)。
Intel进行处理的方式和ARM进行处理的方式实际上总是产生相同的结果,除了进位标志只是相反。因此,只要ARM设置进位,英特尔就会清除它,反之亦然。
两种减法语义学方法都很普遍。ARM方法稍微易于实现,因为它允许直接使用加法器进行减法运算,而无需完全接触进位。采用英特尔的方法,执行减法运算时必须对进位和进位进行补充,但是,在大型方案中,这样做的额外门实际上并不重要。另一方面,对于程序员来说,英特尔的方法更直观,因为考虑到进位标记,并且如果将执行的操作可视化为长减法,则表明借位也更有意义。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句