我在解碼x87 FPU指令時遇到了模糊的情況。請參閱第2A卷Intel指令集手冊[1]頁的第3-380頁中的以下說明。解碼特定x87 FPU指令時的歧義
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
感謝和問候,
Hrishikesh穆拉利
謝謝!這確實幫助我理解它。 :-)那麼這個檢查'> = C0'是否適用於每一條指令?還是隻適用於FPU相關指令? –
這僅適用於x87指令。你基本上首先要檢查'mod = 0b11',在這種情況下,查找64條目大表(modrm&0x3F)中的指令,否則使用reg字段確定指令,rm字段指定操作數。 – user786653
嗯,好的。謝謝! :-) –