解码特定 x87 FPU 指令时存在歧义
我在解码 x87 FPU 指令方面面临着一个不明确的情况。请看以下取自 Intel 指令集手册第 2A 卷第 3-380 页的指令 [1]。
D9 /0 --> FLD m32fp --> Push m32fp onto the FPU register stack.
D9 C0+i --> FLD ST(i) --> Push ST(i) onto the FPU register stack.
这两条指令具有相同的单字节基本操作码 0xD9
。第一条指令的扩展操作码为 0x00
。扩展操作码将在 ModR/M 字节的“reg”字段中指定。但第二条指令是一个 2 字节操作码,具有“添加以获取寄存器”功能。这意味着:
D9 C0 --> FLD ST0
D9 C1 --> FLD ST1
(and so on)
我在区分这两个指令方面有一个小问题。一个小例子是:
现在,假设我得到操作码序列“D9 C1”
。如果我需要检查它是否是指令“FLD m32fp”
,那么我必须检查ModR/M字节的'reg'字段是否为0x00。如果是这样,那么确实使用了指令“FLD m32fp”
。
C1
的二进制表示为“1100 0001”
。假设bit0为LSB,则bit3-bit5(含)构成ModR/M字节“C1”
的'reg'字段。我们看到它确实是0x00
(3个零)。
因此,我将操作码序列“D9 C1”映射到“FLD m32fp”指令。进一步解码,我们看到在这种情况下操作数实际上变成了“ecx”
。但我们看到“FLD ST1”
也有操作码序列“D9 C1”
,这是该操作码序列使用的实际指令。
本质上,我如何确定操作码序列 "D9 C1"
对应于指令 "FLD ST1"
而不是 "FLD ecx"
>?
"FMUL"
指令也会出现非常类似的问题,因为其获取操作数的方式与这里的 "FLD"
相同。
[1] http://www.intel.com/design/intarch/manuals/ 243191.HTM
谢谢和问候,
赫里希凯什穆拉里
I'm facing an ambiguous case with regard to decoding x87 FPU instructions. Take a look at the following instruction taken from page Page 3-380 of Vol 2A Intel's instruction set manual [1].
D9 /0 --> FLD m32fp --> Push m32fp onto the FPU register stack.
D9 C0+i --> FLD ST(i) --> Push ST(i) onto the FPU register stack.
Both these instructions have the same single-byte base opcode 0xD9
. The first instruction has an extension opcode of 0x00
. The extension opcode will be specified in the 'reg' field of the ModR/M byte. But the second instruction is a 2 byte opcode with an 'Add to get register' feature. This means that:
D9 C0 --> FLD ST0
D9 C1 --> FLD ST1
(and so on)
I have a small issue with regard to differentiating these two instructions. A small example is:
Now, supposing I get the opcode sequence "D9 C1"
. If I need to check if it's the instruction "FLD m32fp"
, then I have to check if the 'reg' field of the ModR/M byte is 0x00 or not. If so, then it's indeed the instruction "FLD m32fp"
being used.
The binary representation of C1
is "1100 0001"
. Assuming bit0 is LSB, then bit3-bit5 (inclusive) constitute the 'reg' field of the ModR/M byte "C1"
. We see that it is indeed 0x00
(3 zeros).
So I map the opcode sequence "D9 C1"
to the "FLD m32fp"
instruction. Decoding further, we see that the operand actually becomes "ecx"
in this case. But we see that "FLD ST1"
also has opcode sequence "D9 C1"
, and this is the actual instruction being used for that opcode sequence.
In essence, how can I be sure that the opcode sequence "D9 C1"
corresponds to the instruction "FLD ST1"
and not "FLD ecx"
?
A very similar problems appears for the "FMUL"
instruction too, since takes operands the same way as "FLD"
here does.
[1] http://www.intel.com/design/intarch/manuals/243191.HTM
Thanks and Regards,
Hrishikesh Murali
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这在“A.2.6.转义操作码指令”中进行了描述,相关部分是:
关于问题:
当遇到 x87 指令时,您必须检查 mod/rm 字节是否 >= 0xC0(对应于 mod 字段 0b11 或 3),在这种情况下,请在表 A-10(对于 D9)中查找。在那里您会看到
D9 C1 = FLD ST(0),ST(1)
。当 mod/rm 字节 < 时0xC0 使用的表是 A-9。
D9 01
(mod = 0b00,操作码扩展(reg)= 0b000,rm = 0b001)是“FLD single-real”,查看表 2-2 结果是fld 双字[ecx]
。顺便说一句,没有“FLD ecx”这样的指令,因为您无法直接从整数寄存器加载到 FPU 堆栈上。
This is described in "A.2.6. Escape Opcode Instructions", the relevant part being:
On to the question:
When you encounter an x87 instruction you have to check whether the mod/rm byte is >= 0xC0 (corresponds to a mod field of 0b11 or 3) and in that case look it up in table Table A-10 (for D9). Looking there you see that
D9 C1 = FLD ST(0),ST(1)
.When the mod/rm byte is < 0xC0 the table to use is A-9.
D9 01
(mod = 0b00, opcode extension (reg) = 0b000, rm = 0b001) is "FLD single-real", which looking at Table 2-2 turns out to befld dword [ecx]
.As an aside there is no such instruction as "FLD ecx" since you can't load directly from an integer register onto the FPU stack.