Преобразование строки в числа - PullRequest
0 голосов
/ 24 марта 2019
# replacing all digits in a string with their complement in 9.
.data
    string: .asciiz "123471863"

.text
main:
    # load string's 1st address into the memory
    la $a0, string

    # initialize the loop-counter
    li $t0, 0
    li $t1, 9 # complement envelope for later use

    # start the loop    
start_loop: 
    lb $t2, ($a0) # Take one character from string

    # loop termination condition
    beq $t2, $zero, end_loop # terminate if null-value found

    subi $t2, $t2, 48 # convert it to a digit
    sub $t2, $t1, $t2 # apply complement to $t2
    sw $t2,($a0) # restore the string-byte content

    addi $a0, $a0, 1 # go to next string-byte
    addi $t0, $t0, 1 # increment loop-counter

    j start_loop
end_loop: 

    # print string  
    la $a0, string # load 1st address of the string
    li $v0, 4 # syscall for string print   
    syscall

    move $a0, $t0 # load 1st address of the string
    li $v0, 1 # syscall for string print   
    syscall

    # exit program
    li $v0, 10
    syscall

Программа не работает должным образом. После 1-й итерации регистр $a0 не дает правильное значение. Очевидно, sw $t2,($a0) уничтожает исходный адрес.

Как я могу решить эту проблему?

1 Ответ

1 голос
/ 24 марта 2019

Нет проблем различать ноль и «0». ноль равен 0, а '\ 0' равен 48.

Ваш тест

    beq $t2, $zero, end_loop # terminate if null-value found

совершенно правильно и обнаружит конец строки.

Что неверно в вашем алгоритме.

Способ дополнить число в C будет:

while(c=*str){
  c=c-'0' ; // transform the number to integer
  c=9-c;    // complement it
  c += '0'; // add 48 to turn it back to a character
  str++;
}

Вам не хватает последнего преобразования в символ.

Если вы измените

    sub $t2, $t1, $t2 # apply complement to $t2

до

    sub $t2, $t1, $t2 # apply complement to $t2
    addi $t2, $t2, 48

все должно работать.

В качестве альтернативы, вы можете упростить ваш алгоритм и заметить, что вычисление c=9-(c-48)+48 эквивалентно c=105-c. Добавить перед start_loop

   li $t4 105 ## 

и заменить три строки

    subi $t2, $t2, 48 # convert it to a digit
    sub $t2, $t1, $t2 # apply complement to $t2
    addi $t2, $t2, 48

по

   sub $t2,$t4,$t2  # complement to 9 directly on char representing the digit
...