2009-11-10 47 views
6

我試着翻譯從& T彙編以下英特爾組件:如何從AT&T ASM翻譯「pushl 2000」英特爾語法在i386

pushl 2000 

現在這個編譯爲:

ff 35 d0 07 00 00  pushl 0x7d0 

但無論我怎麼努力,我不能讓英特爾synax一樣,我已經試過:

intel asm 
disassembly after compiling to at&t 

push 2000 
68 d0 07 00 00   push $0x7d0 

push [2000] 
68 d0 07 00 00   push $0x7d0 

push dword ptr [2000] 
68 d0 07 00 00   push $0x7d0 

push dword ptr 2000 
68 d0 07 00 00   push $0x7d0 

所以我沒有線索,相當於「pushl 2000」的是什麼?

回答

7

我覺得原來的代碼並沒有做你認爲正在做的事情。據MSDEV拆卸是:

003AFCFC FF 35 D0 07 00 00 push  dword ptr ds:[7D0h] 

等於推:

*((DWORD*)2000) 

不推價值2000到堆棧。但是 - 如果這是真的,你想要什麼,然後指令是:

push dword ptr ds:[2000] 

ds:是使用ds段寄存器的指示。段寄存器是從惡劣的16位天保留。主要是cs - 代碼段,ds-數據段和ss-堆棧段(和fs,這是存儲線程本地的地方)。將它們視爲基準偏移到內存中。默認情況下,數據訪問不在ds分段中。

我猜想爲什麼push dword ptr [2000]不起作用是因爲編譯器意識到這對你來說是一件愚蠢的事情,並且「修復它」。通過強制使用前綴ds,表明您確實有意在那裏進行內存訪問。

+0

這確實似乎是正確的翻譯。 我不能說我非常瞭解原始代碼(也不是我真正想要的),但我想將其翻譯爲英特爾語法。 你能解釋「ds:」來自哪裏嗎? – 2009-11-10 18:54:51

+0

好的 - 我在答案中加了一些關於ds的描述。 – Aaron 2009-11-10 19:09:29

+0

你碰巧知道我怎麼可以得到不要這樣聰明? – 2009-11-10 19:11:19

1

對我來說,在GNU彙編2.18,爲32位目標

.intel_syntax 
push dword [2000] 

產生:

0: ff 35 d0 07 00 00  pushl 0x7d0 

和NASM:

push dword [dword 2000] 
+0

相同的代碼爲我生成「0:\t 68 d4 07 00 00 \t推送$ 0x7d4」作爲2.20傳遞它--32。 – 2009-11-10 18:51:34