Вернитесь из процедуры и продолжите цикл, используя регистр $ ra без инструкции JAL - PullRequest
0 голосов
/ 27 марта 2019

В этом цикле сканируется строка, и для каждого символа, если он равен одной из этих букв, выполняется определенная процедура:

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 вернуть процедуру из цикла в этот цикл переключения.

Я думаю, что, возможно, я должен добавить в регистр $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);

1 Ответ

1 голос
/ 28 марта 2019

Это должно работать.

# 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
...