x86只给出十六进制机器码,找出指令的操作数大小?

时间:2013-02-19 16:47:22

标签: x86 disassembly

例如,给定十六进制:83 E4 F0

通过查看英特尔开发人员手册,我可以发现83表示andFO表示-16。查看E4,我可以解码源/目标寄存器是SP还是ESP。

因此,我可以得出结论,十六进制表示and $-16, %ESPand $-16, %SP。但是,在手册中,这两个都列为83 /4 ib

我如何区分这两者?

2 个答案:

答案 0 :(得分:8)

正如harold所说,默认操作数大小未在指令中编码,但取决于当前的处理器模式。

在实模式和16位保护模式下,默认操作数大小为16位,因此83 E4 F0解码为and $-16, %sp

在32位模式下,操作数大小默认为32位,因此它是and $-16, %esp

在x64模式下,大多数指令再次默认为32位操作数大小(除了分支和间接使用堆栈的那些,例如推送,弹出,调用和返回),因此它再次解码为and $-16, %esp

可以使用前缀覆盖默认操作数大小。例如,前缀66h在32位和16位操作数大小之间切换,因此66 83 E4 F0在16位模式下解码为and $-16, %esp,在32位或64位时解码为and $-16, %sp模式。要获得64位操作数大小,您需要使用设置了W位的REX prefix,因此48 83 E4 F0解码为and $-16, %rsp(但仅限于64位模式!)。

答案 1 :(得分:0)

在保护模式下,它只能是32位版本,16位和64位版本都需要带前缀的大小覆盖字节,在这种情况下,16位版本需要0x66前缀覆盖,因此您得到66:83 E4 F0。英特尔在AND的描述中明确说明了这一点:

  

在64位模式下,指令的默认操作大小为32位。

和066H的参考,第2.2.1节:

  

操作数大小覆盖前缀允许程序在16位和32位之间切换   操作数大小。两种尺寸都可以是默认尺寸;使用前缀选择非默认值   大小