【发布时间】: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
感谢和问候,
赫里希凯什·穆拉利
【问题讨论】: