C语言数组运算代码转MIPS汇编报错,求问题排查与解决方法
错误排查与修复方案
代码问题定位
- 核心错误:未初始化数组基地址寄存器。你使用
$s6作为数组A的基地址、$s7作为数组B的基地址,但全程没有用la指令加载两个数组的起始地址到对应寄存器,寄存器初始值为随机值,直接导致数组访问时触发非法内存访问错误。 - 格式问题:输出结果未添加换行符,和原C代码的输出格式不一致,多段输出会连在一起显示。
- 规范问题:你使用了
s系列寄存器,按照MIPS调用约定,s寄存器属于被调用者保存寄存器,如果你的代码没有子函数调用可以直接使用,若需要严格遵守规范可以替换为t系列临时寄存器,不需要额外做栈保存操作。
修复后的完整MIPS代码
.globl main .data A: .word 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 B: .word 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 str1:.asciiz "Please, type a number for g:" str2:.asciiz "Please, type a number for h:" str3:.asciiz "The 1st result is:" str4:.asciiz "The 2nd result is:" newline: .asciiz "\n" .text main: # 初始化数组基地址(原代码缺失的核心逻辑) la $s6, A la $s7, B li $v0,4 # 输出提示输入g的字符串 la $a0,str1 syscall li $v0, 5 # 读取g的值 syscall move $s1, $v0 # $s1 = g li $v0,4 # 输出提示输入h的字符串 la $a0,str2 syscall li $v0, 5 # 读取h的值 syscall move $s2, $v0 # $s2 = h # 计算f = -g + b[h] sll $t0,$s2,2 # t0 = 4 * h add $t0,$t0,$s7 # 得到B[h]的内存地址 lw $t0,0($t0) # t0 = B[h] sub $s0,$t0,$s1 # -g + B[h]等价于B[h] - g move $t3,$s0 # t3存储第一个结果f # 计算f1 = a[b[g] + 1] sll $t0,$s1,2 # t0 = 4 * g add $t0,$t0,$s7 # 得到B[g]的内存地址 lw $t0,0($t0) # t0 = B[g] addi $t0,$t0,1 # t0 = B[g]+1 sll $t0,$t0,2 # 乘以4得到数组A的偏移量 add $t0,$t0,$s6 # 加上A数组基地址得到目标内存地址 lw $s0,0($t0) # s0 = A[B[g] +1] move $t4, $s0 # t4存储第二个结果f1 # 输出第一个结果 li $v0,4 la $a0,str3 syscall move $a0,$t3 li $v0,1 syscall li $v0,4 la $a0, newline syscall # 输出第二个结果 li $v0,4 la $a0,str4 syscall move $a0,$t4 li $v0,1 syscall li $v0,4 la $a0, newline syscall li $v0,10 syscall
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

