Return 从一个过程开始,并在没有 JAL 指令的情况下使用 $ra 寄存器继续一个循环

Return from a procedure and continue a cycle using $ra register without the JAL instruction

这个循环扫描一个字符串,对于每个字符,如果等于那个字母之一,则转到特定过程:

switch:
    add     $t1, $zero, $t2
    add     $t1, $t1, $s2      # $s2 is the address of a string
    lb      $t0, 0($t1)

    blt     $t0, 0x41, done
    bgt     $t0, 0x45, done

    beq     $t0, 0x41, algoA   # These are the jump at the procedure
    beq     $t0, 0x42, algoB   # The parameter in input are setted
    beq     $t0, 0x43, algoC   # Before that SWITCH
    beq     $t0, 0x44, algoD
    beq     $t0, 0x45, algoE

endSwitch:
    add     $t2, $t2, 1
    beq     $t2, $s1, done
    j       switch
done:

对于学校项目,我需要每个 "Algo" 标签必须是一个过程。

先定义输入参数。

我不知道如何使用命令 jr $ra return 从程序到 switch-while 循环。

我在想也许我必须在 $ra 注册处添加 endSwitch: 标签地址。

我不相信这是正确的。

这里是伪代码:

while x <= len(string)
    switch string[x]
        case A: algoA(); x++;
        case B: algoB(); x++;
        case C: algoC(); x++;
        case D: algoD(); x++;
        case E: algoE(); x++;
        default: x = len(string);

这应该有效。

# void Sw(const char*);
#   will call:
#     extern void algoA(void), algoB(void),
#       algoC(void), algoD(void), algoE(void);
Sw:
    .set reorder
    addiu   $sp, $sp, -32 # reserve 32 bytes on stack:
                          # 8 unused
                          # 8 for $s0 and $ra
                          # 16 reserved for calls to algoX()
                          # (32 to ensure $sp is properly aligned)
    sw      $s0, 20($sp) # save $s0 on stack
    sw      $ra, 16($sp) # save $ra on stack

    move    $s0, $a0 # algoX() will preserve $sX regs

Sw_loop:
    lbu     $t0, 0($s0) # read a char

    addiu   $t0, $t0, -65 # translate 65(A)...69(E) to 0...4
    sltiu   $t1, $t0, 5 # all others will translate to 5 or more
    beqz    $t1, Sw_done # done if 5 or more

    la      $t1, Sw_table # $t1 = address of Sw_table[]
    sll     $t0, $t0, 2 # multiply 0...4 by 4 to index Sw_table[]
    addu    $t0, $t0, $t1 # $t0 = address into Sw_table[]

    lw      $t0, 0($t0) # $t0 = address of algoX()
    jalr    $t0 # call algoX()

    addiu   $s0, $s0, 1 # advance the address to the next char
    b       Sw_loop # repeat

Sw_done:
    lw      $s0, 20($sp) # restore $s0
    lw      $ra, 16($sp) # restore $ra
    addiu   $sp, $sp, +32 # free stack space
    jr      $ra # return

Sw_table: # table of addresses of algoA()...algoE()
    .word   algoA
    .word   algoB
    .word   algoC
    .word   algoD
    .word   algoE