MARS MIPS32如何将GCD算法改写为支持传参的汇编函数子程序
MIPS32 辗转相减求GCD子程序实现
改造核心规则
MARS环境下遵循MIPS32标准函数调用约定即可,完全匹配你要求的传参返回规则:
- 入参通过
$4($a0)、$5($a1)传入两个待计算的非负整数 - 返回值通过
$2($v0)传回最大公约数结果 - 子程序调用通过
jal 函数标签实现,返回地址会自动存在$ra寄存器,子程序执行完用jr $ra跳回调用点
改造后完整可运行代码
代码包含测试主程序和独立的gcd子程序,可直接在MARS中运行验证:
.text # 测试主程序:可自行修改传入的参数值验证结果 main: addiu $a0, $zero, 49 # 传入第一个参数49 addiu $a1, $zero, 42 # 传入第二个参数42 jal gcd # 调用GCD子程序 # 执行到此处时$v0中即为GCD计算结果,可直接在MARS寄存器面板查看 # GCD独立子程序 gcd: move $v0, $a1 beq $a0, $zero, gcd_exit gcd_loop: beq $a1, $zero, ret_a0 slt $t0, $a1, $a0 bne $t0, $zero, sub_a_from_b slt $t1, $a0, $a1 bne $t1, $zero, sub_b_from_a beq $t1, $zero, sub_b_from_a # 两数相等时走减法分支,下一轮循环直接退出 sub_a_from_b: sub $a0, $a0, $a1 j loop_end sub_b_from_a: sub $a1, $a1, $a0 j loop_end loop_end: j gcd_loop ret_a0: move $v0, $a0 gcd_exit: jr $ra # 子程序返回,回到调用点的下一条指令
关键改动说明
- 移除了原代码开头硬编码给
$4、$5赋值的逻辑,参数完全由调用者传入,实现函数复用 - 原代码用到的临时寄存器
$9、$10替换为标准别名$t0、$t1,不影响运行的同时可读性更高,直接写数字编号也能正常运行 - 新增子程序返回指令
jr $ra,这是顺序执行代码和可调用子程序最核心的差异 - 该子程序属于叶子函数(内部不调用其他子程序),不需要额外做栈保存操作,执行效率更高;如果后续需要在子程序内嵌套调用其他函数,只需要在入口处把
$ra和用到的saved系列寄存器压栈,返回前弹出即可。
内容的提问来源于stack exchange,提问作者Winchester260
相关产品推荐
相关产品推荐

