5

我已经学习了一半以上,并且我熟悉有符号和无符号整数如何以位表示的概念,我知道这似乎是一个奇怪的问题,答案很明显,但我我想知道对于其中一个被认为是有符号而另一个被认为是无符号的一对数字,使用加法之类的算术运算是否有意义,我想到了如下多个示例,它们将产生正确的结果:

10000001(1 字节整数,被视为无符号,相当于 129)
+
11111111(1 字节整数,被视为有符号(二进制补码系统),相当于 -1)


10000000(1 字节整数,在无符号逻辑中相当于 128)

现在,如果上限值在 AL 寄存器中,我们有以下指令代码(GAS 格式):

addb -1, %al

然后 EFLAGS 寄存器的进位标志 (CF) 将在操作完成后设置,并通知实际上没有发生的溢出,可能是因为在溢出方面有一个无符号数 EFLAGS 寄存器的溢出标志 (OF)应该参考。所以我很困惑做这样的事情是否明智。

4

5 回答 5

6

在数学上,您不添加有符号或无符号数。只有值模 2 32(假设您有 32 位寄存器)。这些值涵盖了 2 32个连续整数的范围,但您可以自由地将该范围解释为几乎从任何地方开始。“签名”和“未签名”只是这样的两种解释。

换句话说,对于 4 位寄存器,“1011”的无符号解释是 11,而有符号解释是负 5。但是只有一个值(数学家通常称之为“11 模 2 4 ”,因为数学家传统上喜欢无符号解释)。例如,如果您将“0110”添加到该值(在有符号和无符号解释中都是“六”),那么您会得到“0001”,这是正确的值:减五加六产生一,十一加六是十七,当减少模 2 4时也等于一(十七是一加十六;“减少模 2 4 ”是关于除以十六 [即 2 4 ] 并仅保留余数)。

另一种说法是:数值的(二进制)位数在概念上是无限的。CPU 寄存器只保留最右边的 32 位。按照惯例,无符号解释是假设所有最左边的位都为零。带符号的解释是假设,按照惯例,所有最左边的位都具有与位 31 相同的值(即全部为零,或全部为一)。无论哪种方式,当您执行加法(或减法或乘法)时,进位从右到左传播,而不是相反,因此那些被忽略的位的值对 32 位结果没有任何影响。所以只有一个“加法”操作码,它一点也不关心它的操作数在程序员的大脑中是“有符号”还是“

执行与模运算不兼容的操作时,必须考虑符号性。转换成十进制数字序列进行显示就是这样的操作。然而,更常见的情况是比较。模 2 32的值没有排序;它们处于一种循环循环中(当您将 1 添加到 2 32 -1 并减少模 2 32时,您会回到 0)。只有当您考虑整个整数范围内的整数时,比较才有意义。此时,您必须决定是使用有符号解释还是无符号解释。这就是为什么 x86 处理器同时提供jg(如果大于则跳转,有符号解释)和ja(如果高于则跳转,无符号解释)的原因。

于 2011-01-10T15:17:37.477 回答
3

在二进制级别,只有一个加法运算:

 0101 + (5)
 1010 = (unsigned 10 or signed -6)
--------
 1111   (unsigned 15 or signed -1)

进位和溢出标志呢,它们都是根据简单的规则设置的。如果我们认为操作数是无符号的,则CF 可用于检测溢出流,如果我们认为它们都已签名,则 OF 可用于检测溢出流。这两个标志都是根据结果设置的,由您决定使用哪一个。

OF标志的实际公式是

OF = CF xor MSB_of_result.

这意味着如果我们添加两个正数(我们认为是有符号的),那么如果结果是负数,那么它就会溢出。

于 2011-01-10T09:45:55.363 回答
3

一个数字或运算是有符号还是无符号只是解释的问题。当你做加法时会发生什么,这两个数字加在一起形成100000001位标志(因为它“离开了前端”)。然后由您的后续操作来解释这意味着什么(如果您在其他地方使用该位,就好像您将该操作视为未包装的无符号加法;如果您丢弃该位,就好像您正在做一个有符号的添加)。

于 2011-01-10T09:33:15.383 回答
1

"Signed" and "unsigned" are interpretations. An assembly instruction will generally have the interpretation documented. I am not aware of any architecture where there's an ADD-SIGNED-UNSIGNED instruction that interprets one of its arguments as a signed value and one as unsigned. There seems to be little value in it, too. With 2s complement integer arithmetic, the only difference would be in some flag registers anyway.

于 2011-01-10T09:56:04.467 回答
1

我发现这篇关于我主要关心的问题的非常好的文章,阅读文章后答案很清楚。

于 2011-01-15T09:40:27.397 回答