【问题标题】:Ambiguity in decoding specific x87 FPU instructions解码特定 x87 FPU 指令的歧义
【发布时间】:2011-11-21 06:03:13
【问题描述】:

在解码 x87 FPU 指令方面,我遇到了一个模棱两可的情况。看看下面的指令摘自第 2A 卷英特尔指令集手册 [1] 的第 3-380 页。

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

感谢和问候,
赫里希凯什·穆拉利

【问题讨论】:

    标签: opcode fpu x87


    【解决方案1】:

    这在“A.2.6. Escape Opcode Instructions”中有描述,相关部分是:

    如果 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(对应于 0b11 或 3 的 mod 字段)并在这种情况下在表 A-10 中查找(对于 D9 )。看那里你会看到D9 C1 = FLD ST(0),ST(1)。

    当 mod/rm 字节 D9 01 (mod = 0b00, opcode extension (reg) = 0b000, rm = 0b001) 是“FLD single-real”,查看表 2-2 原来是 fld dword [ecx]。

    顺便说一句,没有“FLD ecx”这样的指令,因为您不能直接从整数寄存器加载到 FPU 堆栈上。

    【讨论】:

    • 谢谢!这确实帮助我理解它。 :-) 所以这个检查 '>=C0' 适用于每条指令,对吧?还是只适用于FPU相关指令?
    • 这仅适用于 x87 指令。您基本上首先要检查 mod = 0b11 是否在这种情况下查找 64 条目大表 (modrm & 0x3F) 中的指令,否则使用 reg 字段来确定指令和 rm 字段操作数。跨度>
    • 我在“invlpg”指令和“rdtscp”指令中遇到了类似的问题。 “invlpg”的操作码为“0f 01”,扩展名为“07”。 “rdtscp”指令的操作码为“0f 01 f9”。如果我们检查“f9”的第 3-5 位,它会解析为 0x07。如果遇到“0f 01 f9”,如何知道是“invlpg”(modr/m为0xf9)还是“rdtscp”?
    • 使用更新版本的IA 64 and 32 ASDM Vol 2 并查阅表格“A.4.2 操作码扩展表”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多