具有32位寄存器的双精度整数减法(MIPS) [英] double precision integer subtraction with 32-bit registers(MIPS)

查看:197
本文介绍了具有32位寄存器的双精度整数减法(MIPS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习计算机算法.我使用的书(帕特森和轩尼诗)列出了以下问题.

编写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/addsubu/addu的操作区别的理解是,溢出异常是在sub/add中生成的,而不是在subu/addu中生成的.与sltsltu指令不同,sub/addsubu/addu都将操作数的位相减/相加,并且对有符号或无符号操作数的解释对结果没有影响.

问题1
我从给定的解决方案作者中推断出,正在处理溢出检测,而我在解决方案中没有想到.我对吗?还有其他我想念的东西吗?

问题2
假设我的上述推论是正确的,为什么在使用addusubu减去无符号双精度的情况下,作者为什么关闭了溢出检测?

解决方案

对于加法和减法,有符号操作数和无符号操作数之间没有区别,除了溢出的概念.当结果的数值与所获得的位序列的解释不匹配时,就会发生溢出.

例如,考虑8位序列(MIPS具有32位寄存器,但对于我的示例而言,8位更容易).让我们假设使用无符号解释:一个8位序列表示一个介于0到255(含)之间的数值.如果我将10010011(数值147)添加到01110110(数值118),则得到00001001(数值9). 9不等于147 + 118.我得到该结果,因为数学值为265,无法容纳8位.加法结果将需要9位,但高阶第9位已被丢弃.

现在,想象一下具有 signed 解释的相同示例. 10010011现在具有数值-109. 01110110的数值仍为118,而获得的结果(00001001)的数值为9.-109和118的数学和为9,因此没有溢出.

这意味着溢出的概念取决于您如何解释值.有符号和无符号解释的加法机制是相同的(对于相同的位输入序列,您将获得相同的输出位序列-这是对负符号值使用二进制补码的全部要点),但溢出处理有所不同. /p>

MIPS体系结构提供了在溢出时触发异常的方法.从概念上讲,对32位字有三个可能的加法运算:

  • 一个默默忽略溢出的附加项(结果被截断)
  • 当有符号的溢出发生时(如果输入和输出序列被解释为有符号的数字,则存在溢出)会引发异常的加法
  • 当无符号溢出发生时(如果输入和输出序列被解释为无符号数字,则存在溢出)会引发异常的加法运算

MIPS实现了前两种加法,分别具有adduadd操作码.在MIPS文档中,它们分别称为 unsigned signed算术.没有用于在未签名的溢出上引发异常的操作码.实际上,C编译器仅使用addu,但是对于带符号的类型,他们可以使用add(C标准允许这样做,但是会破坏很多现有代码). Ada编译器使用add,因为Ada强制执行溢出检查.

话虽如此...

Patterson和Hennessey希望在64位整数上实现有符号和无符号算术.对于无符号算术,他们不希望任何异常,因此使用addusubu.对于有符号算术,他们希望当数学结果不适合带有有符号解释的 64位序列时发生异常.他们不希望因处理低32位半码时出现一些虚假的类似溢出的情况而引发异常.这就是为什么他们在下部使用subu的原因.

您的解决方案是错误的,因为它可能在不应该解决的地方引发异常.假设您要从-2000000000(减去20亿)中减去2000000000(20亿).数学结果为40亿(40亿).这两个操作数及其结果肯定适合64位(可表示范围是-9223372036854775808至9223372036854775807).因此,对于64位带符号算术,没有溢出:不应有异常.但是,在这种情况下,您的第一个sub将报告溢出. sub适用于32位值和带符号的 32位算术.其操作数将为01110111001101011001010000000000和10001000110010100110110000000000.请注意,这些值均适合32位:这些值的32位带符号解释分别为正负20亿.但是,相减结果为40亿,并且不适合32位(作为有符号数).因此,您的sub引发异常.

根据经验,溢出检测的作用是依赖于符号解释,这会影响最高有效位的处理.对于大整数算术,除最高有效位以外的所有单词均应视为无符号,因此在任何地方都addu/subu.第一步,如果您首先专注于无符号算术,那么没有任何例外(那么,您只需使用addusubu,并且永远不要使用 addsub),事情会更容易理解. ).

I am learning computer arithmetic. The book I use(Patterson and Hennessey) lists the below question.

Write mips code to conduct double precision integer subtraction for 64-bit data. Assume the first operand to be in registers $t4(hi) and $t5(lo), second in $t6(hi) and $t7(lo).

My solution to the answer is

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

However the author given solutions for this problem are as below

For signed double precision integers,

subu $t3, $t5, $t7   
sltu $t2, $t5, $t7  
add  $t6, $t6, $t2
sub  $t2, $t4, $t6

For unsigned double precision integers,

subu $t3, $t5, $t7   
sltu $t2, $t5, $t7  
addu $t6, $t6, $t2
subu $t2, $t4, $t6

My understanding of the difference in operation of sub/add and subu/addu is that overflow-exception is generated in sub/add and not in subu/addu. Both sub/add and subu/addu subtract/add the bits of the operands and the interpretation of the operands being signed or unsigned makes no difference to the result unlike in slt and sltu instructions.

Question 1
I am inferring from the author given solutions that overflow detection is being handled whereas I did not think of the same in my solution. Am I right? Is there any other thing I am missing?

Question 2
Assuming that my above inference is right, why is overflow detection switched off for the author provided solutions in the case of subtraction of unsigned double precision by the use of addu and subu?

解决方案

For addition and subtraction, there is no difference between signed and unsigned operands, except for the notion of overflow. An overflow is what happens when the numerical value of the result does not match the interpretation of the sequence of bits that you obtain.

For instance, consider 8-bit sequences (MIPS has 32-bit registers, but 8 bits are easier for my examples). Let us assume unsigned interpretation: an 8-bit sequence represents a numerical value between 0 and 255 (inclusive). If I add 10010011 (numerical value 147) to 01110110 (numerical value 118) then I get 00001001 (numerical value 9). 9 is not equal to 147+118. I get that result because the mathematical value is 265, which cannot fit in 8 bits. The addition result would have required 9 bits, but the upper ninth bit has been dropped.

Now, imagine the same example with the signed interpretation. 10010011 now has numerical value -109. 01110110 still has numerical value 118, and the obtained result (00001001) has value 9. The mathematical sum of -109 and 118 is 9, so there is no overflow.

This means that the notion of overflow depends on how you interpret the values. The addition mechanics are the same for both signed and unsigned interpretations (for the same input sequences of bits, you get the same output bit sequence -- this is the whole point of using two's complement for negative signed values) but overflow handling differs.

The MIPS architecture provides means for triggering exceptions on overflow. Conceptually, there are three possible addition operations on 32-bit words:

  • an addition which silently ignores overflows (result is truncated)
  • an addition which raises an exception when a signed overflow occurs (there is an overflow if the input and output sequences are interpreted as signed numbers)
  • an addition which raises an exception when an unsigned overflow occurs (there is an overflow if the intput and output sequences are interpreted as unsigned numbers)

The MIPS implements the first two kinds of additions, with, respectively, the addu and add opcodes. In the MIPS documentations, they are called, respectively, unsigned and signed arithmetics. There is no opcode for raising exceptions on unsigned overflows. In practice, C compilers use only addu, but they could use add for signed types (this is allowed by the C standard, but would break an awful lot of existing code). Ada compilers use add because Ada makes overflow checking mandatory.

That being said...

Patterson and Hennessey want to implement signed and unsigned arithmetics on 64-bit integers. For unsigned arithmetics, they want no exception whatsoever, hence they use addu and subu. For signed arithmetics, they want an exception to occur when the mathematical result would not fit on a 64-bit sequence with signed interpretation. They do not want to raise an exception because of some spurious overflow-like condition when processing the low 32-bit halves. This is why they use a subu for the low parts.

Your solution is wrong because it may raise an exception where it should not. Suppose that you want to subtract 2000000000 (two billions) from -2000000000 (minus two billions). The mathematical result is 4000000000 (four billions). The two operands and the result certainly fit in 64 bits (the representable range is -9223372036854775808 to 9223372036854775807). Hence, for 64-bit signed arithmetics, there is no overflow: there should be no exception. However, in that situation, your first sub will report an overflow. That sub works with 32-bit values and signed 32-bit arithmetics. Its operands will be 01110111001101011001010000000000 and 10001000110010100110110000000000. Notice that these values both fit in 32 bits: the 32-bit signed interpretation of these values are, respectively, plus and minus two billions. The subtraction result, however, is four billions, and it does not fit in 32 bits (as a signed number). Thus, your sub raises an exception.

As a rule of thumb, overflow detection is about doing things which depend on signedness interpretation, which impacts handling of the most significant bit. For big integer arithmetics, all words except the most significant shall be treated as unsigned, hence addu/subu everywhere. As a first step, things are easier to understand if you first concentrate on unsigned arithmetics, with no exception (then you just use addu and subu, and never add or sub).

这篇关于具有32位寄存器的双精度整数减法(MIPS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆