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
这个循环扫描一个字符串,对于每个字符,如果等于那个字母之一,则转到特定过程:
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