我在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)
但是不起作用,怎么了?
答案 0 :(得分:0)
$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设置中启用伪指令,则可能必须将($a0)
更改为0($a0)
。
这个掩体$a0
,我不记得MIPS调用约定是否使它易失,以防万一您需要保留它,只需在函数开始时将其复制到t0
然后使用t0
。
答案 1 :(得分:0)
像第二次尝试一样,使用寄存器保存字符串地址是正确的方法。
如果缓冲区大于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