如何使用MIPS执行64位加法和减法?

时间:2014-10-14 02:53:28

标签: assembly mips mips32

我想执行64位加法和减法:

v1v0(HiLo) = a1a0 + a3a2使用MIPS汇编语言(a1a0(HiLo)是第一个64位数字由两个32位数字组成,a3a2(HiLo)是第二个数字

我有:

$a0 = 0xffffffff
$a1 = 0x0
$a2 = 0x1
$a3 = 0x0

我是MIPS的初学者,我不知道如何处理携带。有人可以提供解释解决方案吗?

提前致谢!这是我正在使用的指令集:

http://www.cs.uregina.ca/Links/class-info/201/SPIM-IO/MIPSrefCard.pdf

4 个答案:

答案 0 :(得分:5)

要设置一个数字,即v = a - b与使用负数进行添加相同,即v = a + (-b)。但是,在整数aritmetic中,负数被编码为2-compliment,这与1-compliment + 1相同,而1-compliment则是按位否定。

通过这种方式,我们可以写出:

v1v0 = a1a0 - b1b0
v1v0 = a1a0 + ~b1~b0 + 1

所以,我们可以在汇编中写这个(假设b1 = a3和b0 = a2):

add64: addu  $v0, $a0, $a2    # add least significant word
       nor   $t0, $a2, $zero  # ~a2
       sltu  $t0, $a0, $t0    # set carry-in bit (capturing overflow)
       addu  $v1, $t0, $a1    # add in first most significant word
       addu  $v1, $v1, $a3    # add in second most significant word
       jr $ra
#PS: To capture the carry bit in a unsigned sum is equivalent to test if the sum
# can not be contained in a 32 bit register. I.e. if a0 + a2 > 2^32 - 1

sub64: nor $a3, $a3, $zero    # ~b1
       nor $a2, $a2, $zero    # ~b0
       jal add64    # v1v0 = a1a0 + ~b1~b0
         # adding 1 to v1v0
       ori $a0, $v0, 0
       ori $a1, $v1, 0
       ori $a2, $zero, 1
       ori $a3, $zero, 0
       jal add64
       jr $ra

使用你的想法,我想你会回答你自己的问题:

subu $v0, $a0, $a2 # $v0 = $a0 - $a2 
sltu $v1, $a0, $a2 # $v1 = ($a0 < $a2)? 1:0(subtract 1 if there's a borrow for Lo words) 
subu $a1, $a1, $v1 # $a1 = $a1 - $v1 
subu $v1, $a1, $a3 # $v1 = $a1 - $a3

答案 1 :(得分:1)

MIPS架构不提供进位标志(也不提供任何其他标志!)。根据{{​​3}}页面,当添加两个正数给出负数时(或反之亦然),发生需要进位的溢出。

bool carry = (a1[31] == a3[31]) && (v1[31] != a1[31])这样翻译成MIPS程序集的东西应该可以工作。

答案 2 :(得分:0)

一般来说,在添加多位数字时,您需要完成您在二年级学到的知识。添加每个&#34;列&#34;。

 12    89
+34   +33
---   ---
 46   122

第一个很容易,因为没有&#34;携带&#34;发生。在第二种情况下,您必须在十位列中实际添加3个数字:8 + 3 + 1(从一列进位)。然后第二列也进行了100。

你需要做同样的事情,但你将在每个&#34;列&#34;中添加32位。幸运的是,由于您是二进制文件,因此只能从第一列到第二列携带一位。

答案 3 :(得分:0)

算法add64应为:

   addu  $v0, $a0, $a2    # add least significant word
   nor   $t0, $a2, $zero  # ~a2
   sltu  $t0, $t0, $a0    # **~a2 < a0 to check carry generation**
   addu  $v1, $t0, $a1    # add in first most significant word
   addu  $v1, $v1, $a3    # add in second most significant word
   jr $ra

我们可以用a0 + a2&gt;检查进位。 2 ^ 32 - 1,但请记住二进制:

2 ^ n - 1 = a2 + ~a2(例如:a2 = 0110,~a2 = 1001,a2 + ~a2 = 1111 = 2 ^ 4 - 1,n = 4)

因此,a0 + a2> a2 + ~a2 =&gt; a0&gt; 〜A2