解码特定 x87 FPU 指令时存在歧义

发布于 2024-12-17 05:00:16 字数 1341 浏览 2 评论 0原文

我在解码 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怼怹恏 2024-12-24 05:00:16

这在“A.2.6.转义操作码指令”中进行了描述,相关部分是:

如果 ModR/M 字节在
00H 到 BFH 的范围,ModR/M 字节的位 5、4 和 3 用作操作码扩展,类似于用于 1 字节和 2 字节操作码的技术(请参阅第 A.2.5 节。“操作码
一字节和两字节操作码的扩展”)。如果 ModR/M 字节超出 00H 范围
通过BFH,整个ModR/M字节被用作操作码扩展。

关于问题:

现在,假设我得到操作码序列“D9 C1”。如果我需要检查它是否是指令“FLD m32fp”,那么我必须检查ModR/M字节的“reg”字段是否为0x00。如果是这样,那么确实是使用了“FLD m32fp”指令。

当遇到 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:

If the ModR/M byte is within
the range of 00H through BFH, bits 5, 4, and 3 of the ModR/M byte are used as an opcode extension, similar to the technique used for 1-and 2-byte opcodes (refer to Section A.2.5., “Opcode
Extensions For One- And Two-byte Opcodes”). If the ModR/M byte is outside the range of 00H
through BFH, the entire ModR/M byte is used as an opcode extension.

On to the question:

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.

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 be fld 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文