0

由于处理器遵循将数字表示为 2 的补码的约定,它们如何知道由两个正数相加产生的数字是否仍然是正数而不是负数。

例如,如果我添加两个 32 位数字:

r2包含值- 0x50192E32

示例代码:

add r1, r2, #0x6F06410C
str r1, [r3]

这里设置了溢出标志。现在,如果我想在以后的指令中使用内存中存储的结果(在代码中的某处......现在由于不同的指令让处理器cpsr已更改),如下所示:

ldr r5, [r3]
add r7, r5

由于第一条加法指令的 MSB 中有1 ,即现在 r5的MSB中有1,处理器如何解释该值。因为两个正数相加的正确结果是正数。是否仅仅因为MSB 有 1,它解释为负数?在这种情况下,我们会得到与预期不同的结果。

例如,在4 位机器中:

2 的补码:4=0100 和 5=0101;-4=1100 和 -5=1011

现在4+5=9并且如果它作为 1001 存储在寄存器/内存中,然后如果它被另一条指令访问并且给定处理器以 2 的补码格式存储数字并检查 MSB并认为它是负数7.

如果这一切都取决于程序员,那么如何将正确的结果存储在 reg/mem 中。无论如何,我们可以对我们的代码做些什么来存储正确的结果?

4

2 回答 2

2

如果您关心溢出条件,那么您需要在状态寄存器被其他操作覆盖之前检查溢出标志 - 根据所涉及的语言,这可能会导致生成异常,或者使用重试操作更长的整数类型。但是,许多语言(例如 C)并不关心溢出条件 - 如果结果超出类型范围,您只会得到不正确的结果。如果用这种语言编写的程序需要检测溢出,它必须自己实现检查——例如,在加法的情况下,如果操作数具有相同的符号,但结果不同,则存在溢出。

于 2016-09-02T16:03:25.277 回答
2

我知道我和其他人一样已经多次讨论过这个问题。

进位标志可以被认为是加法的无符号溢出标志,它也是借用标志或不借用标志进行减法,具体取决于您的架构。v 标志是加法(减法)的有符号溢出标志。您是唯一一个知道或关心加法是否签名的人,对于加法/减法无关紧要。

它是什么标志或什么架构并不重要,您必须确保如果您关心结果(无论是结果还是标志),您必须尽可能长时间地保留该信息,直到您需要使用它,这不是处理器的工作,也不是指令集,也不是一般的体系结构。它在寄存器中寻找答案,就像在标志中寻找答案一样,这完全取决于程序员。如果您关心,请保留状态。这个问题就像在说你如何解决这个问题:

if(a==b)
{
}
stuff;
stuff;
I want to do the if a == b thing now.

程序员在您需要使用它时而不是在其他时间进行比较,这完全取决于您,在比较时保存比较结果,然后在您检查时检查条件需要使用它。

于 2016-09-02T17:33:28.647 回答