32位x86中SIB字节00 100 101组合异常及mov eax,[addr]编码问题
让我一步步给你拆解这两个问题:
问题1:32位模式下SIB字节00 100 101的问题
这个SIB字节(拆成二进制是SS=00、Index=100、Base=101,十六进制就是0x25)根本是非法的无效编码,处理器完全不买账,一执行就会触发异常。具体原因得结合32位模式的SIB规则掰扯清楚:
- Index字段是
100,对应esp寄存器——但x86 32位模式下esp不能当索引寄存器用,所以这个值的实际意思是「不使用索引寄存器」。 - Base字段是
101,对应ebp寄存器。而32位模式下,当ModR/M字节的Mod=00(也就是指定要用SIB寻址时),Base=ebp的组合是处理器保留的无效组合。因为Mod=00, R/M=101已经被用来直接表示[disp32](不带基址的32位位移寻址),SIB里再凑出Base=ebp+Mod=00的组合完全是冗余且不合法的,根本没有对应的有效寻址方式。
问题2:32位模式下用SIB编码
mov eax, [addr]失败的原因 你说的没错,64位模式下因为Mod=00, R/M=101被改成了RIP相对寻址,所以绝对地址的[addr]必须用SIB编码,但32位模式的规则完全不一样,核心原因有两个:
- 32位模式根本不需要用SIB实现
[addr]:这种单纯的绝对地址寻址(也就是[disp32])已经有更直接的编码方式——要么用单字节opcode的A1 addr(专门给mov eax, [disp32]用的指令),要么用8B 05 addr(通用的mov r32, [disp32],ModR/M字节是0x05,对应Mod=00, R/M=101)。SIB本来就是用来处理复杂寻址的(比如[base + index*scale + disp]这种),完全没必要用它来处理这种简单的绝对寻址。 - 32位模式的SIB规则压根凑不出这种编码:退一步说,你硬要想用SIB模拟的话,得构造
Mod=00, R/M=100(指定用SIB),然后让SIB表示「无基址、无索引,只有32位位移」——但32位模式的SIB根本没有这种合法组合。SIB必须绑定一个基址寄存器,唯一能沾点边的是用Base=ebp+Mod=00,但正如问题1所说,这种组合是非法的,处理器不认,反汇编器自然也解析不出来,执行时触发异常就不奇怪了。
而64位模式修改了ModR/M和SIB的规则,允许用SIB的Base=rbp, Index=rsp(无索引)组合来表示绝对地址的[disp32],所以才能正常工作。
内容的提问来源于stack exchange,提问作者melkyades
相关产品推荐
相关产品推荐

