You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在MARS4_5运行交叉编译的MIPS汇编代码报错的修复咨询

修复MARS 4.5中MIPS汇编代码的运行错误

看起来你是用GNU交叉编译器生成了MIPS汇编,但MARS对汇编语法的兼容性和GAS(GNU汇编器)有差异,所以出现了这些错误。下面逐个解决每个问题:

错误1和2:.align/.ascii不能出现在text段

GNU汇编用.rdata表示只读数据段,但MARS更常用.rodata作为只读数据段的标识(虽然部分版本也支持.rdata,但换成.rodata更稳妥)。另外,确保所有数据相关的伪指令(.align.ascii)都在数据段内,不要混入text段。

错误3和4:1不是合法操作符、1f操作数类型错误

这是GAS的本地标签语法数字+f表示向前跳转的标签),MARS不支持这种格式。你需要把这类本地标签替换成普通的、有意义的标签名,比如skip_div_check

错误5:$31操作数类型错误

j指令在MIPS中是绝对跳转,只能接受地址作为操作数;而$31是返回地址寄存器ra,要跳转到寄存器存储的地址,应该用jr $ra(跳转寄存器指令),而不是j $31

额外需要移除的GAS专属伪指令

GNU汇编生成的.frame.mask.fmask是用于调试和栈帧描述的伪指令,MARS不识别这些,需要直接删除。


修复后的完整汇编代码

.file 1 "test3.c"
.rodata
.align 2
$LC0: .ascii "Array of numbers: \n\000"
.align 2
$LC1: .ascii "%d \000"
.align 2
$LC2: .ascii "\n\n\000"
.align 2
$LC3: .ascii "Array of prime numbers: \n\000"
.align 2
$LC4: .ascii "Max prime numbers: \n\000"
.align 2
$LC5: .ascii "%d\000"
.text
.align 2
.globl main
.ent main
main:
addiu $sp,$sp,-72
sw $ra,64($sp)
sw $fp,60($sp)
sw $s0,56($sp)
move $fp,$sp
sw $sp,40($fp)
li $2,1000 # 0x3e8
sw $2,20($fp)
sw $0,24($fp)
lw $2,20($fp)
sll $2,$2,2
addiu $2,$2,7
addiu $2,$2,7
srl $2,$2,3
sll $2,$2,3
subu $sp,$sp,$2
addiu $2,$sp,16
addiu $2,$2,7
srl $2,$2,3
sll $2,$2,3
sw $2,44($fp)
lw $2,24($fp)
sll $2,$2,2
addiu $2,$2,7
addiu $2,$2,7
srl $2,$2,3
sll $2,$2,3
subu $sp,$sp,$2
addiu $2,$sp,16
addiu $2,$2,7
srl $2,$2,3
sll $2,$2,3
sw $2,48($fp)
la $4,$LC0
jal printf
sw $0,16($fp)
$L2:
lw $2,16($fp)
lw $3,20($fp)
slt $2,$2,$3
beq $2,$0,$L3
lw $2,16($fp)
sll $2,$2,2
lw $3,44($fp)
addu $s0,$2,$3
jal rand
sw $2,0($s0)
lw $2,16($fp)
sll $2,$2,2
lw $4,44($fp)
addu $2,$2,$4
la $4,$LC1
lw $5,0($2)
jal printf
lw $2,16($fp)
addiu $2,$2,1
sw $2,16($fp)
j $L2
$L3:
la $4,$LC2
jal printf
la $4,$LC3
jal printf
sw $0,16($fp)
$L5:
lw $2,16($fp)
lw $3,20($fp)
slt $2,$2,$3
beq $2,$0,$L6
sw $0,32($fp)
li $2,1 # 0x1
sw $2,28($fp)
$L8:
lw $2,16($fp)
slt $2,$2,$3
bne $2,$0,$L9
lw $2,16($fp)
sll $2,$2,2
lw $4,44($fp)
addu $2,$2,$4
lw $3,0($2)
lw $2,28($fp)
div $0,$3,$2
bne $2,$0,skip_div_check
break 7
skip_div_check:
mfhi $2
bne $2,$0,$L10
lw $2,32($fp)
addiu $2,$2,1
sw $2,32($fp)
$L10:
lw $2,28($fp)
addiu $2,$2,1
sw $2,28($fp)
j $L8
$L9:
lw $3,32($fp)
li $2,2 # 0x2
bne $3,$2,$L7
lw $2,24($fp)
sll $2,$2,2
lw $4,48($fp)
addu $3,$2,$4
lw $2,16($fp)
sll $2,$2,2
lw $4,44($fp)
addu $2,$2,$4
lw $2,0($2)
sw $2,0($3)
lw $2,24($fp)
sll $2,$2,2
lw $3,48($fp)
addu $2,$2,$3
la $4,$LC1
lw $5,0($2)
jal printf
lw $2,24($fp)
addiu $2,$2,1
sw $2,24($fp)
$L7:
lw $2,16($fp)
addiu $2,$2,1
sw $2,16($fp)
j $L5
$L6:
la $4,$LC2
jal printf
lw $2,24($fp)
blez $2,$L13
la $4,$LC4
jal printf
lw $4,48($fp)
lw $2,0($4)
sw $2,32($fp)
li $2,1 # 0x1
sw $2,16($fp)
$L14:
lw $2,16($fp)
lw $3,24($fp)
slt $2,$2,$3
beq $2,$0,$L15
lw $2,16($fp)
sll $2,$2,2
lw $3,48($fp)
addu $2,$2,$3
lw $3,0($2)
lw $2,32($fp)
slt $2,$3,$2
bne $2,$0,$L16
lw $2,16($fp)
sll $2,$2,2
lw $4,48($fp)
addu $2,$2,$4
lw $2,0($2)
sw $2,32($fp)
$L16:
lw $2,16($fp)
addiu $2,$2,1
sw $2,16($fp)
j $L14
$L15:
la $4,$LC5
lw $5,32($fp)
jal printf
lw $sp,40($fp)
sw $0,36($fp)
j $L1
$L13:
lw $sp,40($fp)
li $2,-1 # 0xffffffffffffffff
sw $2,36($fp)
$L1:
lw $2,36($fp)
move $sp,$fp
lw $ra,64($sp)
lw $fp,60($sp)
lw $s0,56($sp)
addiu $sp,$sp,72
jr $ra
.end main

补充说明

  • 我把$16替换成了$s0(MARS里更常用的寄存器别名),这样可读性更好,功能完全一致。
  • 替换了GAS的本地标签1fskip_div_check,解决了标签识别问题。
  • 把末尾的j $31改成了jr $ra,符合MIPS指令集规范。
  • 删除了MARS不支持的.frame.mask.fmask伪指令。

现在你可以把这段代码复制到MARS 4.5中运行,应该就能正常执行了。

内容的提问来源于stack exchange,提问作者Duy Nguyễn Lê Bảo

火山引擎 最新活动