SUB AX,IMM16与SUB EAX,IMM32指令的区分方式探讨
关于SUB指令操作码
2D的操作数大小问题解答 核心结论
操作码2D不存在歧义,其对应的操作数大小由当前代码的操作数大小属性决定,而非指令本身编码额外字节区分。
具体判定规则
- 16位模式/32位模式下带
66H操作数前缀:2D后跟2字节立即数(iw),对应指令SUB AX, imm16。 - 32位模式(无
66H前缀):2D后跟4字节立即数(id),对应指令SUB EAX, imm32。 - 64位模式:
- 默认操作数大小为32位,
2D后跟4字节立即数,对应SUB EAX, imm32; - 若带
REX.W前缀(48H),则对应SUB RAX, imm32(立即数符号扩展为64位); - 若带
66H前缀,2D后跟2字节立即数,对应SUB AX, imm16。
- 默认操作数大小为32位,
关于反汇编工具的解析问题
多数反汇编工具会默认按当前设定的模式(比如默认32位)解析指令。如果工具处于32位模式下,遇到2D后跟2字节数据时,会因期望4字节立即数而无法正确解码。要解析2D iw序列,需将反汇编环境切换为16位模式,或明确指定操作数大小前缀66H。
为何编译器(如gcc)不使用该短格式
编译器通常会优先选择更灵活的指令编码:
- 若立即数可通过符号扩展为8位,会使用更紧凑的
SUB r16, imm8(编码66 83 E8 xx),而非SUB AX, imm16; - 为保证代码在不同模式下的兼容性,编译器更倾向于使用带ModRM字节的通用编码形式,而非依赖模式相关的特殊操作码。
内容的提问来源于stack exchange,提问作者00001H
相关产品推荐
相关产品推荐

