将字符串转换为数字
Converting a string into numbers
# 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
程序未按预期运行。第一次迭代后,$a0
寄存器未给出正确的值。显然,sw $t2,($a0)
正在破坏原始地址。
我该如何解决这个问题?
区分 null 和 '0' 没有问题。 null 为 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
# 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
程序未按预期运行。第一次迭代后,$a0
寄存器未给出正确的值。显然,sw $t2,($a0)
正在破坏原始地址。
我该如何解决这个问题?
区分 null 和 '0' 没有问题。 null 为 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