Преобразовать десятичную строку ASCII в целое число - PullRequest
0 голосов
/ 30 октября 2018

Я закодировал получение строки и преобразование ее в 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 голосов
/ 30 октября 2018

Из документации по системному вызову SPIM :

прочитанная строка имеет ту же семантику, что и подпрограмма библиотеки 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 как терминаторы строки выше, так как я не знаю, на какой платформе вы работаете).

...