ArMIPS中使用浮点指令报错‘Invalid opcode - mtc1’求助
ArMIPS浮点指令报错“Invalid opcode - mtc1”的解决办法
问题背景
使用最新版ArMIPS汇编器编译PS1/N64平台的MIPS代码时,调用li.s等浮点指令会触发Invalid opcode - mtc1错误,且无论调整li.s的行号,报错始终指向代码第3行;针对PS1、N64平台的代码均出现该问题,尝试加载符号地址、直接写入浮点数两种写法均失败。
问题原因
- 指令集未启用浮点支持:ArMIPS的
li.s伪指令会被展开为mtc1(将通用寄存器的值传入浮点寄存器),但如果未显式指定目标架构的FPU支持,汇编器会将mtc1识别为非法指令。 - 行号计算异常:
.include引入的头文件内容会被计入总行数,报错显示的第3行实际是头文件加载后,汇编器处理的第一条浮点相关指令,并非代码中写的li.s所在行。
解决方案
1. 显式指定架构与浮点支持
在代码最开头添加架构声明,确保汇编器启用FPU指令集:
- 针对N64(MIPS R4300,64位FPU):
.arch mips4 .set fp=64 - 针对PS1(MIPS R3000,32位FPU):
.arch mips1 .set fp=32
2. 修正浮点指令的使用方式
ArMIPS的li.s伪指令对直接浮点数的支持有限,建议改用标准加载指令:
- 加载预定义的浮点常量:
l.s $f0, floatdata ; 替换原li.s为l.s,直接加载内存中的浮点值 - 直接使用浮点数时,先在数据段定义常量再加载:
.data temp_float: .float 1.5 .text l.s $f0, temp_float
3. 调整代码结构(解决行号异常)
将架构声明放在.include头文件之前,确保汇编器在处理头文件内容前就完成指令集配置,避免行号计算错误导致的报错位置误导。
修改后的代码示例
针对N64的修正代码
.arch mips4 .set fp=64 .include "\SrcAll\Header.asm" l.s $f0, floatdata infloop: j infloop nop floatdata: .float 1.0 .include "\SrcN64\Footer.asm"
直接加载浮点数的修正代码
.arch mips4 .set fp=64 .include "\SrcAll\Header.asm" nop nop nop .data temp_float: .float 1.5 .text l.s $f0, temp_float infloop: j infloop nop floatdata: .float 1.0 .include "\SrcN64\Footer.asm"
内容的提问来源于stack exchange,提问作者puppydrum64
相关产品推荐
相关产品推荐

