I am studying x86 assembly language via the book called Programming from the Ground Up by Jonathan Barlett. Recently I updated my system to 64-bits platform and problems with the syntax of the assembly code appeared, the pushl instruction to be more specific. I spent some time looking for info on x86_64 isa, but I thought would be better to finish learning the basics of x86. In order to do that I was wondering if there's a way of assembling the older syntax into a 64-bits object, or something like that. Or there were major changes which makes that impossible? I am using Ubuntu 10.10 and GNU portable assembler.
Anyway. Would be nice if you indicate a good book, or any source of info, on the x86_64 or in the differences between it and his predecessor.
edit: Thanks! I got what I needed. Both answers were quite useful. And don't wo开发者_C百科rry, I'm looking forward to let go of the X86.
Linux uses the x86_64 ABI specified here. The best thing you can do is take a read through the bits of the ABI most relevant to your area. Here's a few that come to mind:
- Unlike x86 there is only one calling convention on x86_64; two if you count the fact that Microsoft Windows is totally different again.
- In x86, arguments to functions are commonly passed on the stack. in x86_64, the first few are in registers
rdi
,rsi
,rdx
,rcx
,r8
andr9
for integer types. - Memory address types are all
QWORD
so if you're using full registers (r10
etc) with AT&T syntax you'll needmovq
,addq
etc.
Now, part of the design of x86_64
was that it be backwards-compatible with x86
i.e. able to execute x86
code if the operating system is set up correctly. So, there is nothing wrong with for example doing this:
nasm -felf32 myprog.asm
gcc -o myprog -m32 myprog.o
However, be aware; the more you start to rely on other code being available, the more you need 32-bit copies of everything. Note that this is basically using code in 32-bit mode entirely, complete with calling convention and everything. In short, it should execute on a 32-bit machine too. As Jerry says (+1), you cannot compile 32-bit assembly using 32-bit conventions in 64-bit mode. You have to comply with the 64-bit ABI.
Of course, beyond that, you are free inside your routines to use registers like eax
, just be aware it affects the whole of rax
or rather the half that is `eax.
There are enough differences between 32-bit and 64-bit operation at the assembly language level that you almost certainly wouldn't want to just try to treat 32-bit code as if it was 64-bit code and hope for the best, or anything like that.
When you're working as "close to the metal" as writing assembly language, it's usually for a reason -- you generally wouldn't/won't/don't appreciate the assembler trying to guess at what you really intended, and modifying your code to suit. In some cases you'd just lose the advantages (e.g., speed) and in others it would probably break what you were doing entirely (e.g., when/if it sign extends something to 64 bits that should really have been zero-extended).
精彩评论