NASM中使用大比例因子时出现无效有效地址错误求助
问题原因与解决方案
你的问题本质是违反了x86架构的有效地址格式限制,和NASM本身无关,具体两点:
1. 比例因子必须是2的幂(1、2、4、8)
x86硬件仅允许索引寄存器的比例因子为1、2、4、8这四个值,你的代码里用了100和3,都不符合这个要求,因此NASM报错。你提到把第一个指令比例改成50后错误解决,这应该是误解——50同样不是2的幂,大概率是你调整写法时无意中修正了寻址格式(比如把100*edi改成了100 + edi这类合法格式)。
2. 有效地址不能同时包含两个带比例的索引寄存器
x86的有效地址规则是:位移 + 基址寄存器 + 索引寄存器*比例,其中最多只能有一个寄存器带比例因子。你的第二个指令[dmat+298*edi+3*esi]同时给edi和esi都添加了非合法比例因子,触发了“two index registers”错误;当你把比例改成1后,298*edi依然是非法比例(298不是2的幂),所以报错依然存在。
解决方法
对于非2的幂的比例,必须手动计算内存偏移量,再访问内存,推荐用乘法指令或lea组合计算:
处理第一个指令
; 计算 mat + 100*edi + esi 的偏移 mov eax, edi imul eax, 100 ; eax = edi * 100 add eax, esi ; eax += esi movzx eax, [mat + eax] ; 访问目标内存
处理第二个指令
; 计算 dmat + 298*edi + 3*esi 的偏移 mov eax, edi imul eax, 298 ; eax = edi * 298 mov ebx, esi imul ebx, 3 ; ebx = esi * 3 add eax, ebx ; eax += ebx mov [dmat + eax], eax ; 写入目标内存
如果追求效率,也可以用lea拆分乘法(仅适用于能拆成2的幂之和的情况),比如100=64+32+4:
lea eax, [edi*64 + edi*32] ; eax = edi*(64+32) = edi*96 lea eax, [eax + edi*4] ; eax += edi*4 → edi*100 add eax, esi movzx eax, [mat + eax]
内容的提问来源于stack exchange,提问作者user19980548
相关产品推荐
相关产品推荐

