PCSpim模拟器中MIPS汇编代码编译错误求助
排查PCSpim中MIPS汇编代码的编译错误
看起来你刚入门MIPS汇编,碰到的问题其实都是新手常犯的小细节,我帮你梳理一下代码里的几个关键错误:
1. 数据段地址超出32位范围
你的数据段声明是:
.data 0x100020000
MIPS是32位架构,有效地址必须是32位以内的,0x100020000是36位长度,超出了PCSpim支持的地址范围。你可以改成合法的32位地址,比如:
.data 0x10002000
或者直接省略地址参数,让模拟器自动分配数据段空间:
.data
2. 标签定义格式错误
你把main:和sub1:写在了同一行:
main: sub1:
在MIPS汇编语法中,每个标签必须单独占据一行,否则模拟器无法正确识别标签的位置。应该拆分成两行:
.text main: sub1:
另外注意,sub1:这个标签在当前代码里没有被调用,如果是冗余代码可以直接删掉,避免混淆逻辑。
3. 代码不完整导致的逻辑异常
你的代码最后截断成了s...,当前的ciclo1循环没有终止条件:在addi $t0, $t0, 1之后,既没有跳回ciclo1的跳转指令,也没有判断循环次数的逻辑,这会导致模拟器编译时出错,或者执行时出现异常。
修正后的完整代码示例
我帮你把所有错误修正,同时补全循环逻辑(假设要处理dati1里的5个数据):
.data 0x10002000 dati1: .word 0xC000, 0xF000A000, 0x8000FFFF, 0x23150001, 0x0 .text main: move $t0, $zero la $t1, dati1 ciclo1: lw $t2, 0($t1) move $t3,$t2 bne $t2, $zero, dopo1a ori $t4, $zero, 1 beq $zero, $zero, dopo1b # 无条件跳转到dopo1b dopo1a: slt $t4, $zero, $t2 # 判断$t2是否为正数,正数则$t4=1 dopo1b: bne $t4, $zero, dopo1c # 如果$t4=1(正数或0),跳过取反操作 nor $t3, $t3, $t3 # 对负数取反(nor指令等价于按位取反) addi $t3, $t3, 1 # 加1得到负数的绝对值(补码转原码) dopo1c: sw $t3, 32($t1) # 把结果存到当前地址+32的内存位置 addi $t1, $t1, 4 # 移动到下一个word的地址 addi $t0, $t0, 1 # 循环计数+1 bne $t0, 5, ciclo1 # 循环5次后退出(对应dati1的5个数据) li $v0, 10 # 调用程序退出的系统调用 syscall
额外说明
- 我补全了程序退出的系统调用代码,否则PCSpim执行到代码末尾后会报错。
- 循环逻辑里判断
$t0是否等于5,刚好对应dati1定义的5个.word数据,确保所有元素都被处理。
你可以把这段修正后的代码放到PCSpim里试试,应该就能正常编译运行了。
内容的提问来源于stack exchange,提问作者user7253265
相关产品推荐
相关产品推荐

