Convert Binary to Decimal in MIPS, Assembly MARS -
i trying convert binary decimal in mips language, using mars simulator. program accepts binary number, , conversion, multiplying (shift left number's place $t9). way of saying multiplying each 1 digit 2 raised power of place, , summing result.
i not have understanding of how values stored , communicated between ascii, decimal, , problem "sum" coming out 40,000 rather value of binary number in decimal. doing wrong here?
.data msg1: .asciiz "enter number in base 2 (-2 quit): " msg2: .asciiz "\nresult: " allones: .asciiz "1111111111111111" empty: .space 16 newline: .asciiz "\n" sum: .space 16 summsg: .asciiz "\nsum: " onefound: .asciiz "\none found\n" zerofound: .asciiz "\nzero found\n" .text .globl main main: getnum: li $v0,4 # print string system call la $a0,msg1 #"please insert value (a > 0) : " syscall la $a0, empty li $a1, 16 # load 16 max length read $a1 li $v0,8 # 8 string system call syscall la $a0, empty li $v0, 4 # print string syscall li $t4, 0 # initialize sum 0 startconvert: la $t1, empty li $t9, 16 # initialize counter 16 firstbyte: lb $a0, ($t1) # load first byte blt $a0, 48, printsum addi $t1, $t1, 1 # increment offset subi $a0, $a0, 48 # subtract 48 convert int value beq $a0, 0, iszero beq $a0, 1, isone j convert # iszero: subi $t9, $t9, 1 # decrement counter j firstbyte isone: # 2^counter li $t8, 1 # load 1 sllv $t5, $t8, $t9 # shift left counter = 1 * 2^counter, store in $t5 add $t4, $t4, $t5 # add sum previous sum move $a0, $t4 # load sum li $v0, 1 # print int syscall subi $t9, $t9, 1 # decrement counter j firstbyte convert: printsum: srlv $t4, $t4, $t9 la $a0, summsg li $v0, 4 syscall move $a0, $t4 # load sum li $v0, 1 # print int syscall exit: li $v0, 10 # exit system call syscall
one issue you're decrementing $t9
twice per iteration. should leave first decrement (the 1 after subtracting 48) is, , remove other two.
another issue if parsing string left-to-right, need take length of string account @ point. ideally, you'd setting $t9
length of string instead of 0 (on second line after startconvert
), don't yet know length of string.
one option parse through string beforehand determine length, , set $t9
value.
a more elegant way whole thing in 1 pass: assume string 16 characters long, including delimiter (so, assign 16
$t9
first). suppose string 5 characters long. after loop, sum high factor of 2^(16-5) = 2^11
. observe final value of $t9
11
. can fix error shifting sum register right $t9
many bits.
finally, looks mars putting character of 0x0a
(this pressing enter) onto end of string (except when use 15 characters; uses 0x00
instead, because automatically stops after 15th character before giving chance press enter). on beqz
line, instead of comparing 0
, instead check if $a0 < 48
. take care of both cases, whether delimiter 0x00
or 0x0a
.
here's version fixes:
.data msg1: .asciiz "enter number in base 2 (-2 quit): " msg2: .asciiz "\nresult: " allones: .asciiz "1111111111111111" empty: .space 16 newline: .asciiz "\n" sum: .space 16 summsg: .asciiz "\nsum: " onefound: .asciiz "\none found\n" zerofound: .asciiz "\nzero found\n" .text .globl main main: getnum: li $v0,4 # print string system call la $a0,msg1 #"please insert value (a > 0) : " syscall la $a0, empty li $a1, 16 # load 16 max length read $a1 li $v0,8 # 8 string system call syscall la $a0, empty li $v0, 4 # print string syscall li $t4, 0 # initialize sum 0 startconvert: la $t1, empty li $t9, 16 # initialize counter 16 firstbyte: lb $a0, ($t1) # load first byte blt $a0, 48, printsum # don't think line works addi $t1, $t1, 1 # increment offset subi $a0, $a0, 48 # subtract 48 convert int value subi $t9, $t9, 1 # decrement counter beq $a0, 0, iszero beq $a0, 1, isone j convert # iszero: j firstbyte isone: # 2^counter li $t8, 1 # load 1 sllv $t5, $t8, $t9 # shift left counter = 1 * 2^counter, store in $t5 add $t4, $t4, $t5 # add sum previous sum move $a0, $t4 # load sum li $v0, 1 # print int syscall j firstbyte convert: printsum: srlv $t4, $t4, $t9 la $a0, summsg li $v0, 4 syscall move $a0, $t4 # load sum li $v0, 1 # print int syscall exit: li $v0, 10 # exit system call syscall
Comments
Post a Comment