2012-11-11 44 views
5

我寫的x86/x64的CPU指令編譯器,我似乎無法弄清楚什麼人通過「位移」地址的意思。例如,在這裏詳細說明添加指令: http://www.c-jump.com/CIS77/CPU/x86/X77_0150_encoding_add_edx_displacement.htm在x86/x64添加位移解決

我只是試圖實現add指令,其中寄存器添加到正常的內存地址。問題是,地址是'位移地址'。這是否意味着地址是一個有符號值,是指令位置的偏移量?

+3

您是否正在生成彙編代碼?你不能生成C代碼,還是使用LLVM?或者用http://code.google.com/p/asmjit/或其他庫發佈機器代碼?你對x86/64指令集有很好的理解嗎?您是否學習了http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html –

回答

9

有幾種不同形式的間接操作數在86:

  1. [條]
  2. [REG +位移]
  3. [位移]
  4. [REG *恆定+ REG ]
  5. [reg * constant + reg + displacement]

「位移」只是一個常數,會被添加到地址的其餘部分。如果沒有地址以外的組成部分,它仍然稱爲「位移​​」。這主要是爲了與其他尋址表單保持一致。

另一種方式看它是所有地址的形式是

[REG *恆定+ REG +位移]

隨着每次允許的0

的值的部件的[位移]形式只是位移以外的所有分量均爲零的編碼。

作爲一個編譯器編寫者,最後2種形式特別有趣。他們可以很容易地在一條指令中編碼像pArray[index]->field + 1這樣的東西。

+0

好吧,[reg * constant + reg +位移]如何被編碼到機器指令中?說我有一個數組在內存位置0x00000001,我想訪問它的索引是AL。我想我想使用移動指令並執行MOV AH 0x00000001 [AL]。我認爲這只是[reg +位移]。本頁的第6部分顯示了對R/M字節進行編碼,但它確實令人困惑:http://www.c-jump.com/CIS77/CPU/x86/lecture.html –

+0

請看intel手冊的第2卷。每條指令都指定其編碼形式。列出r/m操作數的編碼形式接受mod/rm字節中的寄存器或內存操作數。 –

+0

看看英特爾手冊的第2卷。每條指令都指定其編碼形式。列出r/m操作數的編碼形式接受mod/rm字節中的寄存器或內存操作數。在第2卷的第2章2.1節中,有一個表格顯示了mod r/m字節的含義。列出[ - ] [ - ]的表格表示使用SIB字節的編碼。 SIB尋址的形式是reg * constant + reg。 mod/rm字節的某些形式表明SIB字節後面是位移。這些給出了reg *常量+ reg +常量形式。有一張表格解釋SIB。 –

3

沒有「特別添加,需要一個排量」,該頁面被不必要的混亂 - 這只是正常的存儲器操作數編碼的一部分。

add是所編碼的相同的方式,所有的ALU-OPS一個相當標準的指令是:存在一種使用al作爲目的地並立即作爲源(04 ib),採用ax/eax/rax作爲目的地和一種特殊情況立即作爲源(+ 05 imm)的add r/m, imm(一個用於8位的目的地,一個用於更寬目的地和符號擴展的8位源,一個用於更寬目的地和來源廣),當然還有一個add r, r/madd r/m, r三個版本。

這只是add r, r/m的一個特殊情況,其中r/m採取位移的形式:請參閱註釋#1 ModRM encoding

所以他們只是指add edx, [sdword]。 (但是他們錯誤地編碼了註冊字段,edx對應於010,而不是011

+0

因此,要將AL(8位寄存器0)添加到內存位置0x00000000, CPU會接受(十六進制)00 05 00000000? –

+0

@RyanBrown是的,這將起作用 – harold

4

該頁面不準確。正如你在反彙編器的輸出中看到的那樣,它所談論的「add that take a displacement」是指形式爲add r[16|32], r/m[16|32]add edx, [0xdisp]。假設它的談論與操作碼0x03 ADD指令,

  • 編碼edx寄存器目的地和指定32位位移作爲MODR/M字節的有效地址將使其的0×15的值(參閱英特爾®64和IA-32架構軟件開發人員手冊第2卷,第41頁,表2-2)。
  • 該指令的作用是在存儲器地址disp添加DWORD到的edx內容。
  • 指令的實際編碼因此將爲:\x03\x15\x00\x00\x00\x01,位移爲1個字節。