求助修复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
相关产品推荐
相关产品推荐

