MARS环境下MIPS汇编sw指令能否仅指定一个参数?
解决MARS中MIPS汇编sw指令压栈报错的问题
嘿,我之前在MARS上写MIPS汇编的时候也碰到过这个指令格式的坑,太懂你的困惑了!咱们一步步来拆解问题:
为什么sw $t0($sp)会报错?
MIPS的存储字指令sw的语法格式是固定的:必须写成 sw $源寄存器, 立即数偏移量($基址寄存器)。这里的偏移量必须是一个立即数(比如0、4、-8这类直接写的数字),不能用寄存器代替。你写的$t0($sp)相当于把$t0当成了偏移量,这完全不符合MIPS的指令编码规则,所以MARS会直接报错。
正确的压栈操作应该怎么写?
要把$t0里的整数压入栈,得记住MIPS栈是向下生长的(从高地址往低地址扩展),所以正确步骤是:
- 先把栈指针
$sp减去4(因为每个整数占4字节),给新数据腾出空间; - 再把
$t0的值存入栈顶位置(也就是偏移量0相对于$sp的地址)。
对应的代码就是:
addi $sp, $sp, -4 # 栈指针下移4字节,预留存储位置 sw $t0, 0($sp) # 将$t0中的整数存入栈顶
如果要循环压入10个输入的数字,只需要在循环里重复这两步就行——每次读入一个数到$t0,然后执行上面的压栈操作。
关于“仅指定一个参数”的疑问
MIPS里的sw指令没有单参数的写法,它必须同时指定源寄存器和带偏移的基址寄存器(哪怕偏移量是0)。如果你尝试只写sw $t0或者sw $sp,MARS会因为指令格式不合法而报错,这是正常的,别怀疑自己!
给你一个完整的示例代码
刚好对应你“输入10个数字压入栈”的作业需求,我写了个可运行的片段,你可以直接在MARS里测试:
.data prompt: .asciiz "请输入一个数字:" .text main: li $t1, 0 # 循环计数器,初始为0 li $t2, 10 # 总共要输入10个数字 loop: bge $t1, $t2, exit # 计数器到10就退出循环 # 打印输入提示 li $v0, 4 la $a0, prompt syscall # 读取用户输入的整数到$t0 li $v0, 5 syscall move $t0, $v0 # 执行压栈操作 addi $sp, $sp, -4 sw $t0, 0($sp) addi $t1, $t1, 1 # 计数器加1 j loop exit: # 可选:弹出栈中所有数字并打印,验证是否正确存储 li $t1, 0 print_loop: bge $t1, $t2, end_program lw $t0, 0($sp) # 从栈顶取出数据 li $v0, 1 move $a0, $t0 syscall # 打印取出的数字 addi $sp, $sp, 4 # 栈指针上移,释放空间 addi $t1, $t1, 1 j print_loop end_program: li $v0, 10 syscall # 退出程序
这个代码里,输入的10个数字会依次被压入栈,最后还会把栈里的数字弹出来打印,方便你验证结果。
内容的提问来源于stack exchange,提问作者ElderFuthark
相关产品推荐
相关产品推荐

