MIPS汇编运行时对齐错误求助:address not aligned on doubleword boundary
解决MIPS汇编中的“address not aligned on doubleword boundary”错误
嘿,这个错误我之前也碰到过——MIPS架构对双精度浮点数的内存操作有严格的对齐要求,必须要存在8字节整数倍的地址上,你的代码里有俩地方踩坑了,我给你拆解下怎么修:
1. 别用双精度指令加载单精度变量
你在.data里定义的s和a都是.float(单精度,4字节),但却用了l.d(双精度加载指令,一次读8字节)来读取它们。这不仅会多读隔壁4字节的未知内存,还很容易触发对齐报错,因为单精度变量的起始地址不一定是8字节对齐的。
改法:
先用l.s加载单精度到浮点寄存器,要是需要转成双精度,再用cvt.d.s指令转换,之后再存。比如原来的:
l.d $f0, s s.d $f0, -16($fp)
改成:
l.s $f0, s # 加载单精度值到$f0 cvt.d.s $f0, $f0 # 把单精度转成双精度,存在$f0里 s.d $f0, -16($fp)# 存到栈上(这里地址要注意对齐)
2. 栈上的双精度存储地址必须8字节对齐
你代码里写的-20($fp)这个地址,算一下就知道不是8的倍数(20除以8余4),而MIPS要求双精度的存储地址必须是8的整数倍,所以s.d $f2, -20($fp)直接触发了对齐错误。
改法:
重新规划栈上的变量地址,确保双精度对应的地址是8的倍数。比如把栈上的地址调整成这样:
- 三个int变量(各4字节)可以放在
-4($fp)、-8($fp)、-12($fp)(这些是4字节对齐,符合int要求) - 双精度变量放在
-16($fp)、-24($fp)(这些是8字节对齐)
把原来的s.d $f2, -20($fp)改成s.d $f2, -24($fp)就ok了。
额外建议:别乱交叉.text和.data段
你的代码里.data和.text来回跳,虽然汇编器可能能处理,但这不是好习惯,建议把所有数据定义都放在.data段,代码全放.text段,看起来清爽多了。
给你贴个修正后的完整代码
.data s: .float 2.1 a: .float 4.5 .text .globl main main: # 先分配栈帧,预留32字节空间(3个int+2个double) addi $sp, $sp, -32 move $fp, $sp # 存储int变量到栈上(4字节对齐即可) li $a0, 0 # a的值 sw $a0, 0($fp) li $a0, 3 # b的值 sw $a0, 4($fp) li $a0, 5 # c的值 sw $a0, 8($fp) # 处理s变量:单精度转双精度后存栈 l.s $f0, s cvt.d.s $f0, $f0 s.d $f0, 16($fp) # 处理a变量(原来的line19错误行) l.s $f0, a cvt.d.s $f2, $f0 # 转成双精度到$f2 s.d $f2, 24($fp) # 正常退出程序 li $v0, 10 syscall
内容的提问来源于stack exchange,提问作者Yazan Fouad Aldbaisy
相关产品推荐
相关产品推荐

