MIPS在函数的参数上使用字符串

时间:2019-06-30 14:27:31

标签: assembly mips mars-simulator

我在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)

但是不起作用,怎么了?

2 个答案:

答案 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