将ASCII十进制字符串转换为整数

时间:2018-10-30 11:17:29

标签: assembly mips spim

我编码为获取字符串并将其转换为int。但是无论我输入什么,结果都只是-1。如果我输入123,则结果为-1;如果我输入-123,则结果为-1。我认为问题是字符串寄存器,但我不知道问题出在哪里。

.globl main
.data
     input : .space 30
.text   
 main:

   li $v0,8 #get string
   la $a0,input
   li $a1, 30
   syscall

   jal str2int   # call the procedure str2int
   move $a0,$v0   # move the return value into $a0
   li $v0,1      
   syscall       # print the result

   li $v0, 10
   syscall        # Exit the program

# register $v0(return value)                         

str2int:
   # Check for sign
   lb $t0,0($a0)   # load the first byte into $t1
   beq $t0,'-',negint # if sign is -,goto negint
   beq $t0,'+',posint # if sign is +,goto posint
   j convert
negint:   li $t1,1       # set flag $t1 to 1(represents negative)
   add $a0,$a0,1   # goto next ASCII character
   j convert   # goto convert
posint:   li $t1,0       # set flag $t1 to 0(represents positive)
   add $a0,$a0,1   # goto next ASCII character
convert:
   li $s0,0       # sum=0
loop:              
   lb $t0,0($a0)   # load the ASCII character into $t1
   beqz $t0,exitloop   # if the character is null, exit the loop
   blt $t0,'0',fail   # if $t1 is a non-digit character,return -1
   bgt $t0,'9',fail
   sub $t0,$t0,48   # convert ASCII digit to decimal digit
   mul $s0,$s0,10   # multiply the previous sum with 10 and
   add $s0,$s0,$t0   # the converted digit to sum
   add $a0,$a0,1   # goto next ASCII character
   j loop       # goto loop
exitloop:
   beq $t1,0,copy   # if sign is +, goto copy
   neg $s0,$s0   # if the sign is -, take negation of integer
copy:   move $v0,$s0   # store the converted integer into $v0  
   j return
fail:    li $v0,-1
return:   jr $ra       # return $v0 to main

1 个答案:

答案 0 :(得分:0)

来自SPIM syscall documentation

  

read字符串与Unix库例程fgets具有相同的语义。它最多将n-1个字符读入缓冲区,并以空字节终止该字符串。如果当前行上的字符较少,它将读取换行符,并再次以空字符终止该字符串。

请注意,很可能在输入字符串的末尾(紧接终止0之前)会有换行符。这将在转换循环中触发错误。您应该以测试终结者的类似方式显式测试这种情况:

    lb $t0,0($a0)        # load the ASCII character into $t0
    beq $t0,13,exitloop  # if the character is CR, exit the loop
    beq $t0,10,exitloop  # if the character is LF, exit the loop
    beqz $t0,exitloop    # if the character is NUL, exit the loop
    ...

(请注意,由于我不知道您在哪个平台上运行,我在上面同时检查了CR和LF作为行终止符)。