MIPS 在函数参数上使用字符串
MIPS use string on arguments of function
我在 MIPS 上有这个函数,它将缓冲区中的字符串的小写字母转换为大写字母:
funcion:
addi $t0,$zero,0
loop:
lb $t1, buffer($t0)
beq $t1, 0, exit_loop
blt $t1, 'a', case
bgt $t1, 'z', case
sub $t1, $t1, 32
sb $t1, buffer($t0)
case:
addi $t0, $t0, 1
j loop
exit_loop:
jr $ra
.data
buffer: .asciiz "Meow"
buffer2: .asciiz "Guau"
我想将它用于 buffer2,如何将类似字符串的参数发送给函数?
我试试这个
la $a0,buffer
jal convertir_a_mayusculas
并更改循环函数
loop:
lb $t1, $a0($t0)
beq $t1, 0, exit_loop
blt $t1, 'a', case
bgt $t1, 'z', case
sub $t1, $t1, 32
sb $t1, $a0($t0)
但是不起作用,怎么了?
$a0($t0)
不是有效的寻址模式,因为它有两个寄存器,好消息是您根本不需要 $t0
:只需递增 $a0
.
funcion:
loop:
lb $t1, ($a0)
beq $t1, 0, exit_loop
blt $t1, 'a', case
bgt $t1, 'z', case
sub $t1, $t1, 32
sb $t1, ($a0)
case:
addi $a0, $a0, 1
j loop
exit_loop:
jr $ra
如果 MARS 设置中未启用 pseudo-instructions,您可能需要将 ($a0)
更改为 0($a0)
。
这个clobber$a0
,我不记得MIPS调用约定是否使它变易变了,如果你需要保留它,就把它复制到t0
开头函数,然后使用 t0
。
在第二次尝试中使用寄存器来保存字符串地址是正确的方法。
如果缓冲区超过 16 位,使用 lb $t1, buffer($t0)
可能会产生问题。它可以在小示例中工作,但在实际代码中很危险。
第二次尝试的主要问题是指令 lb $t1, $a0($t0)
在句法上不正确。 lb
需要一个目标寄存器、一个地址寄存器和一个 必须 是立即数的偏移量。
因此,由于缓冲区的地址已经在 $a0
中,您可以在循环中使用 lb $t1, 0($a0)
并递增 $a0
来访问连续的字符。
loop:
lb $t1, 0($a0) # loads byte at address $a0+0
beq $t1, 0, exit_loop
blt $t1, 'a', case
bgt $t1, 'z', case
sub $t1, $t1, 32
sb $t1, 0($a0)
case:
addi $a0, $a0, 1 # let $a0 point to next char in buffer
j loop
exit_loop:
jr $ra
我在 MIPS 上有这个函数,它将缓冲区中的字符串的小写字母转换为大写字母:
funcion:
addi $t0,$zero,0
loop:
lb $t1, buffer($t0)
beq $t1, 0, exit_loop
blt $t1, 'a', case
bgt $t1, 'z', case
sub $t1, $t1, 32
sb $t1, buffer($t0)
case:
addi $t0, $t0, 1
j loop
exit_loop:
jr $ra
.data
buffer: .asciiz "Meow"
buffer2: .asciiz "Guau"
我想将它用于 buffer2,如何将类似字符串的参数发送给函数?
我试试这个
la $a0,buffer
jal convertir_a_mayusculas
并更改循环函数
loop:
lb $t1, $a0($t0)
beq $t1, 0, exit_loop
blt $t1, 'a', case
bgt $t1, 'z', case
sub $t1, $t1, 32
sb $t1, $a0($t0)
但是不起作用,怎么了?
$a0($t0)
不是有效的寻址模式,因为它有两个寄存器,好消息是您根本不需要 $t0
:只需递增 $a0
.
funcion:
loop:
lb $t1, ($a0)
beq $t1, 0, exit_loop
blt $t1, 'a', case
bgt $t1, 'z', case
sub $t1, $t1, 32
sb $t1, ($a0)
case:
addi $a0, $a0, 1
j loop
exit_loop:
jr $ra
如果 MARS 设置中未启用 pseudo-instructions,您可能需要将 ($a0)
更改为 0($a0)
。
这个clobber$a0
,我不记得MIPS调用约定是否使它变易变了,如果你需要保留它,就把它复制到t0
开头函数,然后使用 t0
。
在第二次尝试中使用寄存器来保存字符串地址是正确的方法。
如果缓冲区超过 16 位,使用 lb $t1, buffer($t0)
可能会产生问题。它可以在小示例中工作,但在实际代码中很危险。
第二次尝试的主要问题是指令 lb $t1, $a0($t0)
在句法上不正确。 lb
需要一个目标寄存器、一个地址寄存器和一个 必须 是立即数的偏移量。
因此,由于缓冲区的地址已经在 $a0
中,您可以在循环中使用 lb $t1, 0($a0)
并递增 $a0
来访问连续的字符。
loop:
lb $t1, 0($a0) # loads byte at address $a0+0
beq $t1, 0, exit_loop
blt $t1, 'a', case
bgt $t1, 'z', case
sub $t1, $t1, 32
sb $t1, 0($a0)
case:
addi $a0, $a0, 1 # let $a0 point to next char in buffer
j loop
exit_loop:
jr $ra