0

I am working on a assignment where I have to input two 64-bit unsigned numbers in decimal and then perform addition and multiplication on them, and output the results in decimal.

Result of addition is stored in $s4 for low half of the number and $s5 for the high half. I have a problem with converting these two values into one string that contains the result in decimal.

After some research I've found out that Method:

You should generate the string from right to left, each time dividing the 2-word number by 10, calculating the remainder and quotient. The remainder is converted to the next character and stored in a string for printing later. The quotient is rewritten into the two words and used in the next iteration.

How to perform divison of 64-bit number by 10 Let A (64 bits) be composed of B and C, where B contains the high end 32 bits and C the low end 32 bits. That is, A = B(2^32) + C. Use divu and remu instructions on B and C to determine the overall quotient and remainder for the 64-bit number A divided by 10.

Here is the procedure that I came up with:

itoa:   
li $t0, 0
li $t3, 0
li $t2, 0
li $t1, 0
li $t5, 0   
li $t6, 0
li $t8, 0   

addiu $t5, $zero, 6 # 2%32%10
addiu $t0,$zero,10 # t0=10
lw $t1, exponent #2^32/10
addu $t2,$t2, $a0 #low half of addition
addu $t3,$t3, $a1 #high half of addition

itoa_loop:      
#B/10
beqz $t3, skip_high
divu $t3, $t0
mflo $t3 #quotient of B
mfhi $t4 #remainder of B
multu $t4, $t5 #multiplying remainders of B/10 and 2^32/10
mflo $t6       

skip_high:
#C/10
divu $t2, $t0
mflo $t2 #quotient of C
mfhi $t4 #remainder of C

addu $t8, $t4, $t6 #summing up remainders
addi $t8, $t8, 48 #convert to ascii
sb $t8, ($t9) #t9 is the output string
addi $t9, $t9, 1

#2^32/10
divu $t1, $t0
mflo $t1 #2^32/10 quotient
mfhi $t5 #2^32%10 remainder

bne $t2, $zero, itoa_loop

sb $zero, ($t9)
jr $ra

It works for 32-bit numbers only unfortunately.

shuk
  • 1
  • 1
  • Welcome to SO. Do you know how to debug? Watch your program execute line by line, check the register values, see where it goes wrong. SPIM supports that AFAIK. – Seva Alekseyev May 28 '20 at 18:55
  • 1
    Debugging in SPIM is kinda meh from what I can see, try MARS instead: http://courses.missouristate.edu/kenvollmar/mars/ – Seva Alekseyev May 28 '20 at 19:05
  • Or even an online MIPS debugger: https://rivoire.cs.sonoma.edu/cs351/wemips/ – Seva Alekseyev May 28 '20 at 19:07
  • I've debugged it in MARS and found out that there is something wrong with the conversion to ASCII. For example if I have sum of remainders equal 14 the line "add $t8, $t8, 48" converts it to char "D", but it should be converted to char "0". No idea what should be changed. – shuk May 28 '20 at 19:25
  • I don't see your fragment ever loading the $t9 register where the string is supposed to go. Also, $t9 is kind of a misnomer; traditionally, the $t registers ($8..$15) go from 0 to 7. Maybe SPIM forgives that... – Seva Alekseyev May 28 '20 at 19:32
  • Yeah the registers is a thing a should take care of, because this whole thing is a mess right now. I am storing the char like this "sb $t8, ($t9)" and it works for the 32-bit numbers, the result is just printed in reverse. I will add later on the reverse string procedure, but for now the biggest issue is to make it work for bigger numbers. – shuk May 28 '20 at 19:39
  • Your example is obviously incomplete. Nobody likes debugging by eyeballing the code; if you want the SO community to engage with your question, **please paste an example that we can build and debug on our end**. – Seva Alekseyev May 28 '20 at 19:41
  • Also, I think you're incrementing your pointer in the wrong direction. You want to start at the end of a buffer and produce digits backwards, like the C in [How do I print an integer in Assembly Level Programming without printf from the c library?](https://stackoverflow.com/a/46301894) – Peter Cordes May 29 '20 at 00:04
  • https://devblogs.microsoft.com/oldnewthing/20180404-00/?p=98435 has some interesting stuff about `mtlo`. I had assumed `div` would divide HI:LO by the source reg, but no, it doesn't. I deleted a previous comment; it seems that 64-bit division by 10 might need 3 `divu` instructions after all, with the last 2 doing 16 new bits each. I'm still not sure why `mul` would be useful, though. – Peter Cordes May 29 '20 at 03:34
  • I just need to figure out how to get this overall remainder for 64-bit number divided by 10, when it is divded into two 32-bit halves :| Maybe it's just the matter of math. – shuk May 29 '20 at 11:56

0 Answers0