You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助修复MARS(MIPS汇编与运行模拟器)代码问题

MIPS汇编代码问题解答

核心疑问解答

1. slt指令操作数对应关系

MIPS的slt Rd, R1, R2指令逻辑清晰:当第一个源寄存器R1的数值小于第二个源寄存器R2的数值时,目标寄存器Rd被设为1;否则Rd设为0。

你当前代码里的slt $2,$2,91存在两个问题:

  • slt的两个源操作数必须都是寄存器,不能直接使用立即数。如果要和立即数做比较,应该用**slti**指令(立即数版本的小于比较),格式为slti Rd, R1, imm,逻辑和slt一致,仅第二个源操作数为立即数。
  • 你将比较结果存回了$2,这会覆盖之前从栈中读出的当前字符值——虽然此处后续未再使用该值,但从代码规范角度,建议避免覆盖仍需使用的寄存器,或明确知晓操作影响。

另外,你提到要与'Z'的ASCII值(0x5A,十进制90)比较,当前循环判断“值小于91”的逻辑是对的(91是0x5B,即'Z'的下一个ASCII值),可以直接用十六进制0x5B替代十进制91,提升代码可读性。

2. 初始值li $2,65是否需要修改

65是字母'A'的ASCII值(0x41),如果你想从字母表起始字符'A'开始循环,这个初始值完全正确。若改成li $2,0x5A('Z'的ASCII值),循环起始点会变为'Z',和“从字母表起始值开始”的需求不符。因此不需要修改该初始值,除非你要从'Z'开始反向循环。

修正后的代码

针对上述问题,修正后的代码如下:

.data
$LC0:
.ascii "%c \000"
.text

main:
addiu $sp,$sp,-40
sw $31,36($sp)
sw $fp,32($sp)
move $fp,$sp
li $2,65 # 0x41,初始化起始字符'A'
sw $2,24($fp)
b $L2
nop

$L3:
lw $5,24($fp)
la $4, $LC0 # 把格式字符串地址传入$4(printf第一个参数寄存器)
jal printf
nop

lw $2,24($fp)
addiu $2,$2,2 # 每次加2,打印A、C、E...Y
sw $2,24($fp)
$L2:
lw $2,24($fp)
slti $t0, $2, 0x5B # 用slti和0x5B(91)比较,结果存到$t0避免覆盖$2
bne $t0,$0,$L3 # 结果为1(当前值<91)时跳回循环
nop

move $2,$0
move $sp,$fp
lw $31,36($sp)
lw $fp,32($sp)
addiu $sp,$sp,40
jr $31
nop

补充说明:原代码中lui $t1, 100和addiu $t1,$t2,-100是无效操作,printf的第一个参数需要格式字符串的地址,因此添加la $4, $LC0将地址传入参数寄存器$4,保证printf能正确执行。

内容的提问来源于stack exchange,提问作者TheMaiar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 13:30:53