2011-01-31 181 views
0

我正在通过Jonathan Barlett编写的一本名为“Programming from Ground Up”的书来研究x86汇编语言。最近我将系统更新到64位平台,出现了汇编代码语法问题,pushl指令更具体。我花了一些时间在x86_64 isa上寻找信息,但我认为完成学习x86的基础知识会更好。为了做到这一点,我想知道是否有方法将较旧的语法组合成一个64位对象,或类似的东西。还是有重大的变化,这使得不可能? 我使用Ubuntu 10.10和GNU便携式汇编程序。在64位平台上运行的32位汇编代码

无论如何。如果您在x86_64上指出一本好书或任何信息来源,或者它与他的前任之间存在差异,那么这样做会很好。

编辑:谢谢!我得到了我需要的东西。两个答案都非常有用。别担心,我期待着放开X86。

回答

3

Linux使用指定的x86_64 ABI here。您可以做的最好的事情是读取与您所在地区最相关的ABI位。下面是几个想到的:

  • 与x86不同,在x86_64上只有一个调用约定;如果您再次指出微软Windows完全不同的事实,那么两者是相同的。
  • 在x86中,函数的参数通常在堆栈上传递。在x86_64中,前几部分是整数类型的寄存器rdi,rsi,rdx,rcx,r8r9
  • 内存地址类型都是QWORD所以如果你使用全寄存器(r10等)与AT & T语法,你需要movqaddq

现在,x86_64设计的一部分是它与x86向后兼容,即如果操作系统设置正确,则可以执行x86代码。所以,举例来说,没有什么不对的,例如:

nasm -felf32 myprog.asm 
gcc -o myprog -m32 myprog.o 

但是,要知道;越是开始依赖其他可用代码,就越需要所有内容的32位副本。请注意,这基本上是在32位模式下完全使用代码,完成调用约定和一切。总之,它也应该在32位机器上执行。正如Jerry所说(+1),无法在64位模式下使用32位约定编译32位程序集。你必须遵守64位ABI。

当然,除此之外,你可以在你的例程中免费使用像eax这样的寄存器,只要注意它会影响整个rax,或者说是影响eax的一半。

2

在汇编语言级别的32位和64位操作之间有足够的差异,您几乎可以肯定不会试图将32位代码视为64位代码,并希望最好的,或类似的东西。

当你在编写汇编语言时“接近金属”时,它通常是有原因的 - 你一般不会/不会/不会欣赏汇编器试图猜测你的东西真正的意图,并修改你的代码以适应。在某些情况下,你会失去优点(例如速度),而在另外一些情况下,它可能会破坏你完全正在做的事情(例如,如果/如果它的符号扩展到应该实际上已经被零扩展的64位)。