2009-11-10 48 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