How do I perform 64-bit addition and subtraction with MIPS?

I want to do 64 bit addition and subtraction:

v1v0(HiLo) = a1a0 + a3a2

using MIPS assembly language ( a1a0(HiLo)

is the first 64-bit number made up of two 32-bit numbers, and a3a2(HiLo)

is the second)

and I have:

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

      

I am new to MIPS and I am not sure how to handle hyphenation. Can anyone provide a solution with an explanation?

Thanks in advance! This is the set of instructions I'm using:

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

+3


source to share


4 answers


To subtract a number i.e. v = a - b

, the same as adding with a negative number, i.e. v = a + (-b)

... But in integer arithmetic, a negative number is encoded as a 2-compliment, the same as 1-compliment + 1, and a 1-compliment is bitwise negation.

Thus, we can write that:

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

      

so we can write this in assembly as (assuming b1 = a3 and 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

      


using your ideas i think you will answer your own question:

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

      

+5


source


MIPS architecture does not provide carry flag (or any other flags!). According to this page , a carry overflow occurs when two positive numbers are added, giving a negative number (or vice versa).



Something like bool carry = (a1[31] == a3[31]) && (v1[31] != a1[31])

translated into MIPS build should work.

+1


source


In general, you need to do what you learned as second class when adding multi-digit numbers. Add each column.

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

      

The first is easy, because no "transfer" occurs. In the second case, you had to add 3 numbers in ten columns: 8 + 3 + 1 (carry over from one column). Then the second column is also done to make 100.

You need to do the same, but you add 32 bits to each column. Fortunately, since you are in binary, you can only carry one bit from the first column to the second.

0


source


The add64 algorithm should be:

   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

      

We can check for carry with a0 + a2> 2 ^ 32 - 1, but remember that in binary:

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

Thus, a0 + a2> a2 + ~ a2 => a0> ~ a2

0


source







All Articles