6

在此处的 ARM 文档中,它说:

进位发生:

...如果减法的结果是正数或零...

我从这个关于 SO 的答案中知道,当存在无符号下溢(即被减去的数字(减数)大于从(被减数)中减去的数字)时,进位标志设置为减法。

所以考虑这个例子:

r1 = 5
r2 = 10
CMP r1, r2

比较 (CMP) 执行此处提到的减法,然后设置适当的标志。在这种情况下,r1-r2 = 5-10 = -5。由于这里有无符号下溢(5 < 10),我们希望设置进位标志。但根据 ARM 文档,结果 (-5) 不是正数或零,因此不应设置进位标志。(假设我们查看签名的结果;否则根据文档将永远不会发生进位)。

ARM文档有错吗?我的误解是什么?

4

2 回答 2

7

ARM 使用反向进位标志进行借位(即减法)。这就是为什么在没有借位时设置进位并在有时清除。这个设计决策使得构建 ALU 稍微简单一些,这也是一些 CPU 这样做的原因。

于 2018-10-30T13:39:35.063 回答
2

我们不需要所有 32 位来显示减法发生了什么

5 - 3

从小学开始,我们就知道 5 - 3 = 5 +(-3) 这就是它在逻辑上的实现方式,二进制补码的一个特点是得到 -3 你反转并加一个所以

5 - 3

      1
   0101
 + 1100
=========

完成它

  11011
   0101
 + 1100
=========
   0010

所以一般情况下(不是特定于处理器)5 - 3 = 2。误位的进位和进位都是一个,因此不会设置有符号溢出,进位是 1。但是某些架构以及反转第二个操作数并且进位(到 lsbit)也反转进位,称为借位。有些不。

当您查看大于和小于进位位的定义时,有些人会记录这一点

5 - 4

  11111
   0101
 + 1011
=========
   0001

5 - 5

  11111
   0101
 + 1010
=========
   0000

5 - 6

  00011
   0101
 + 1001
=========
   1111

5 - 7

  00011
   0101
 + 1000
=========
   1110

这表明,如果您查看原始执行,它会在操作数 b 等于操作数 a 时切换,当 b 小于 a 时,它会在 b 等于或大于 a 时设置,这很清楚。因此,如果架构保持不变,您可以在大于或等于的一种情况下使用进位位表示大于或小于(但不等于)由该标志定义,并且哪个方向取决于架构(如果它反转执行成借位)。在另一个方向,您要么翻转操作数并使用一位,要么使用 N 和 C 来确定大于或等于的值。

与其他一些文档不同,arm 文档向您展示了每个条件的标志是什么,并且知道上述内容或能够在简单的测试中重复它,您可以确定它们是否反转。指令 sbb 是用借位减法而不是 sbc 用进位减法,但它本身并不暗示该指令集如何解释该位。

于 2018-10-30T18:08:14.500 回答