'Hexadecimal to decimal in MIPS. I'm getting really strange and negative output from $s3 could really use some help for I am all out of ideas
Been trying to write this hex to decimal converter in MIPS. Should take in up to 8 arguments (string) from command line, all hex starting with "0x", 4 bytes long and terminated with null character after every argument.
$s1= number of args; $s0-->args(0).
For these Program Arguments: 0x1A 0xF1 0x0B3:
.data
buffer: .space 32
args: .asciiz "\nProgram arguments:\n"
space: .asciiz " "
d_rep: .asciiz "\n\nInteger values:\n"
newLine: .asciiz "\n"
maxVal: .asciiz "Maximum value:\n"
.text
main:
add $t9, $zero, $zero # t9 will be max value
add $s1, $a0, $0 # store number of program arguments
add $s2, $a1, $0 # store address of where program arguments are
addi $s0, $0, 0 # use s0 as index for looping
addi $s7, $zero, 0 # used as index for print loop
add $s6, $s1, $0 # store numArgs for printloop
add $s5, $s2, $0 # store address for printloop
addi $t5, $zero, 16
addi $t6, $zero, 0
la $a0, args # load and print "Program arguments" string
li $v0, 4 # print
syscall
printloop:
beq $s7, $s6, printInt # only print as many times as there are args
lw $a0, 0($s5) # get the first word
li $v0, 4 # print
syscall
la $a0, space # print a space between words
li $v0, 4 # print
syscall
addi $s5, $s5, 4 # increment to next word
addi $s7, $s7, 1 # increment printloop counter
j printloop # loop again if there are more args
printInt:
la $a0, d_rep # print "Decimal values:"
li $v0, 4 # print
syscall
while:
beq $s0, $s1, done # while $s0 <= numArgs
lb $t1, 2($s2) # load s2[2] into
addu $t2, $zero, $t1 # make a copy so we dont lose place
subiu $sp, $sp, 4
convert:
beqz $t2, postConv # while t2 != null
blt $t2, 65, convNumber # if less than value of A then got a num
subiu $t3, $t2, 0x37 # -55 for uppercase letter
sll $t3, $t3, 4 # sll by 4 is same as mult by 16
sw $t3, ($sp) # store word to do some addition
addiu $t2, $t2, 1 # increment t2
subiu $sp, $sp, 4 # increment sp
j convert # go back to convert
convNumber:
addu $t3, $zero, $t2 # put t2 into t3 for to do some math
subiu $t3, $t3, 0x30 # -48 for number
sll $t3, $t3, 4 # sll by 4 is same as mult by 16
sw $t3, ($sp)
addiu $t2, $t2, 1 # increment t1
addiu $sp, $sp, 4 # increment sp
j convert # jump back to convert
postConv:
addi $sp, $sp, 4 # load the second value
lw $s4, ($sp) # load the first value
addi $sp, $sp, 4
# sll $s4, $s4, 4
lw $s3 ($sp)
addu $s3, $s3, $s4 # add em up for converted decimal
move $a0, $s3 # move to a0 so they pint
li $v0, 1 # print
syscall
addiu $s0, $s0, 1 # increment loop counter
addiu $s2, $s2, 4 # increment to next word
ble $t9, $t6, newMax # check for a new max value
j while # jump back to loop
newMax:
addu $t9, $zero, $t6 # got a new max so save it
j while
done:
la, $a0, newLine
li $v0, 4
syscall
la, $a0, newLine
li $v0, 4
syscall
la, $a0, maxVal
li $v0, 4
syscall
move $a0, $t9
li $v0, 1
syscall
la, $a0, newLine
li $v0, 4
syscall
li $v0, 10 # end program
syscall
My output is this:
Program arguments:
0x1A 0xF1 0x0B3
Integer values:
-2121474836290
Maximum value:
0
-- program is finished running --
But it should be : 26 241 179. And maxValue should be: 241
I would be very grateful if someone could help me debug this. Thank you! :D
Solution 1:[1]
You should be able to debug this yourself. Single stepping the code to find this error is trivial. If you don't know how to debug code, then suggest you focus on learning that. Check each instruction to make sure it is doing what you expect, and if not, that's where the problem is.
argv is a pointer to pointers to characters — if we consider that a pointer to characters is a string, then we can describe argv as a pointer to strings. To get single character from argv we have to choose which of the strings, then choose a character from that string.
You are doing this correctly when printing the program arguments, but are not following that approach for accessing their bytes, instead you're accessing individual bytes from the pointers themselves, which of course makes no sense. Put another way, you're missing an indirection aka dereference.
This kind of error should stand out to you like a flashing warning sign when you single step over the lb $t1, 2($s2) instruction — because you are expecting it to fetch the ascii 1, 0x31, but are getting an 0xff instead. When you see that an instruction is not getting what you expect that's where and when to rethink things: it is doing what you told it to do but you can observe that is not what you want.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
