为何NASM与YASM生成mov dx,word [esi-5]时带67操作码?
关于NASM/YASM生成67前缀及缩短指令的问题解答
问题1:为何NASM与YASM会生成67操作码字节?
先理清两个前缀的核心作用:
66h是操作数大小前缀:x86-64模式下默认操作数为32/64位,这个前缀会强制切换为16位,对应你提到的mov dx, word [rsi-5](dx是16位寄存器)。67h是地址大小前缀:x86-64默认用64位寻址模式(对应rsi/rdi这类64位地址寄存器),当指令里用了32位地址寄存器esi时,必须加这个前缀告诉CPU:“我要切换到32位寻址方式访问内存”。
你的指令是mov dx, word [esi-5],这里用了32位的esi而非64位的rsi,所以汇编器必须添加67h前缀来适配32位寻址,再配合66h前缀指定16位操作数——两个前缀分工明确:66h管操作数宽度(把edx缩成dx),67h管寻址模式(把rsi换成esi),缺一不可。
问题2:是否能生成更短的4字节指令?
完全可以!核心是把指令里的esi换成64位的rsi。
x86-64模式下使用默认的64位寻址寄存器rsi时,不需要67h地址前缀。对应的指令mov dx, word [rsi-5]生成的机器码就是66 8B 56 FB,正好4字节——也就是你提到的“仅66配合8B 56 FB”的情况。
如果必须保留esi(比如有特定兼容性需求),那67h前缀是硬性要求,无法缩短到4字节;但只要改用rsi,就能去掉多余的地址前缀,得到更紧凑的4字节指令。
内容的提问来源于stack exchange,提问作者Kamil.S
相关产品推荐
相关产品推荐

