x86查找仅给定十六进制机器码的指令的操作数大小?

x86查找仅给定十六进制机器码的指令的操作数大小?,x86,disassembly,X86,Disassembly,例如,给定一个十六进制:83 E4 F0 通过阅读《英特尔开发人员手册》,我可以看出83表示和,FO表示-16。查看E4,我可以解码源/目标寄存器是SP或ESP 因此,我可以得出结论,十六进制表示和$-16,%ESP或和$-16,%SP。但是,在本手册中,这两个都列为83/4 ib 如何区分这两者?在受保护模式下,它只能是32位版本,16位和64位版本都需要前缀大小覆盖字节,在这种情况下,16位版本需要0x66前缀覆盖,因此您得到66:83 E4 F0。英特尔在和的说明中明确说明了这一点: 在6

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

通过阅读《英特尔开发人员手册》,我可以看出
83
表示
FO
表示
-16
。查看
E4
,我可以解码源/目标寄存器是SP或ESP

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


如何区分这两者?

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

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

以及066H的参考,第2.2.1章:

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


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

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

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

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


可以使用前缀覆盖默认操作数大小。例如,前缀66h在32位和16位操作数大小之间切换,因此
66 83 E4 F0
在16位模式下解码为
和$-16,%esp
,在32位或64位模式下解码为
和$-16,%sp
。要获得64位操作数大小,需要将与W位集一起使用,因此
48 83 E4 F0
解码为
和$-16,%rsp
(但仅在64位模式下!)。

视情况而定。如果在实模式下,或者如果当前段/选择器的默认操作数大小设置为16位,它将作为
和sp,-16执行。“通常”是32位版本。我不是下选者,但你的回答与哈罗德的评论有点矛盾…@Hery:假设他处于32位或64位保护模式(这是“标准”,考虑到他没有提到相反的内容),生成16位或64位版本的唯一方法是通过覆盖前缀。这与harold一点也不矛盾,这是保护模式的定义(除非他使用的是16位CPU,已经有30年的历史了……)。事实上,286中也引入了16位保护模式。我的意思是矛盾的,就像你在上一个回答中说的“肯定”,而harold说的“取决于”。现在你解释得更清楚了。有没有办法让我知道处理器在什么模式下运行?没有更多的上下文。字节从哪里来?记忆?文件在洗过的瓶子里找到的?在梦中找到你?十六进制字符串来自一个文件,但编码为ASCII字符串(这整件事是一个课程项目,因此是简单的格式)。是否有类似寄存器的东西存储处理器的操作模式?没有寄存器。处理器以16位实模式启动。在受保护模式下,模式由全局或本地描述符表中代码段描述符中的某些位指定。因此,如果只有十六进制字节,则必须另外指定模式,例如在问题描述中或作为工具的命令行选项。您很可能会默认为32位模式,因为这是目前最常见的情况。