用32位寄存器(MIPS)的双精度整数减法
-
30-09-2019 - |
题
我正在学习计算机算术。我使用的书(Patterson和Hennessey)列出了以下问题。
编写MIPS代码以进行64位数据的双精度整数减法。假设第一款操作数在寄存器中$ t4(hi)和$ t5(lo),第二$ t6(hi)和$ t7(lo)。
我对答案的解决方案是
sub $t3, $t5, $t7 # Subtract lo parts of operands. t3 = t5 - t7
sltu $t2, $t5, $t7 # If the lo part of the 1st operand is less than the 2nd,
# it means a borrow must be made from the hi part
add $t6, $t6, $t2 # Simulate the borrow of the msb-of-low from lsb-of-high
sub $t2, $t4, $t6 # Subtract the hi's. t2 = t4 - t6
但是,作者给出了这个问题的解决方案如下
对于签名的双精度整数,
subu $t3, $t5, $t7
sltu $t2, $t5, $t7
add $t6, $t6, $t2
sub $t2, $t4, $t6
对于未签名的双精度整数,
subu $t3, $t5, $t7
sltu $t2, $t5, $t7
addu $t6, $t6, $t2
subu $t2, $t4, $t6
我对操作差异的理解 sub/add
和 subu/addu
是在 sub/add
而不是 subu/addu
. 。两个都 sub/add
和 subu/addu
减去/添加操作数的位和对要签名或未签名的操作数的解释对结果没有任何影响 slt
和 sltu
指示。
问题1
我从作者中推断出给定解决方案,即处理溢流检测,而我在解决方案中也没有考虑过。我对吗?我还有其他东西吗?
问题2
假设我的上述推断是正确的,为什么在通过使用无符号双重精度的情况下,为作者提供了溢出检测 addu
和 subu
?
解决方案
对于加法和减法,除了溢出概念外,签名操作数和未签名操作数之间没有差异。当结果的数值与您获得的位序列的解释不匹配时,溢出是什么。
例如,考虑8位序列(MIPS具有32位寄存器,但我的示例更容易)。让我们假设未签名的解释:8位序列代表0到255之间的数值值(包含在内)。如果我将10010011(数值147)添加到01110110(数值118),则获得00001001(数值9)。 9不等于147+118。我之所以得到这个结果,是因为数学值为265,不能符合8位。加法结果将需要9位,但上数率已删除。
现在,想象一下与 签 解释。 10010011现在具有数值-109。 01110110仍然具有数值118,并且获得的结果(00001001)具有值9。-109和118的数学总和为9,因此没有溢出。
这意味着溢出的概念取决于您如何解释值。对于签名和未签名的解释,加法机制都是相同的(对于相同的输入序列,您可以得到相同的输出位序列 - 这是使用两个对负符号值的补充的重点),但溢出处理也有所不同。
MIPS架构提供了用于触发溢出异常的手段。从概念上讲,有 三 可能对32位单词进行加法操作:
- 默默地忽略溢出的添加(结果被截断)
- 当签名溢出发生时,会增加例外的添加(如果将输入和输出序列解释为签名数字,则溢出)
- 当未签名的溢出发生时,会增加例外的添加(如果将插入和输出序列解释为无签名数字,则溢出)
MIPS分别使用 addu
和 add
opcodes。在MIPS文档中,它们分别被称为 未签名 和 签名算术. 。在未签名的溢出上没有升高异常的操作码。实际上,C编译器仅使用 addu
, ,但他们可以使用 add
对于签名类型(C标准允许使用,但会破坏很多现有代码)。 ADA编译器使用 add
因为ADA强制进行溢出检查。
话虽如此...
帕特森(Patterson)和轩尼诗(Hennessey)希望在64位整数上实施签名和未签名的算法。对于未签名的算术,他们不希望任何例外,因此使用 addu
和 subu
. 。对于签名的算术,他们希望当数学结果不适合时发生例外 64位 带有签名解释的序列。他们不想引起例外,因为处理低32位的半分半型时有一些虚假的溢出状态。这就是为什么他们使用 subu
对于低零件。
您的解决方案是错误的,因为它可能会在不应该的情况下引起例外。假设您想从-2000000000(减数为20亿)中减去200000 000亿(20亿)。数学结果为4000000000(四亿)。这两个操作数和结果肯定适合64位(代表范围是-9223372036854775808至92223372036854775807)。因此,对于64位签名的算术,没有溢出:应该没有例外。但是,在这种情况下,您的第一个 sub
将报告溢出。那 sub
使用32位值并签名 32位 算术。它的操作数将是011101111111111001010000000000和10001000110010100111111110000000000。请注意,这些值都适合32位:这些值的32位签名解释分别是这些值的解释,分别是,加上和减去20亿。但是,减法结果为40亿,它不适合32位(作为签名的数字)。因此,你 sub
提出例外。
根据经验,溢流检测是关于做取决于签名解释的事情,这会影响处理最重要的位。对于大整数算术,除了最重要的单词均应将其视为未签名,因此 addu
/subu
到处。作为第一步,如果您首先专注于未签名的算术,那么事情就更容易理解,而无例外(然后您只使用 addu
和 subu
, , 和 绝不 add
或者 sub
).