汇编文件介绍
GCC 产生的汇编代码对我们来说有点儿难读。一方面,它包含一些我们不需要关心的信息,另一方面,它不提供任何程序的描述或它是如何工作的描述。例如,假设我们用如下命令生成文件mstore.s。
------------------------mstore.c-------------
long mult2(long, long);
void multstore(long x, long y, long *dest) {
long t = mult 2(x, y);
*dest = t; }
-----------------------------------------------
linux> gcc -Og -S mstore.c
mstore.s 的完整内容如下:
.file "010-mstore.c"
.text
.globl multstore
.type multstore, ©function
multstore:
pushq %rbx
movq %rdx, %rbx
call mult2
movq %rax, (%rbx)
popq %rbx
ret
.size multstore, .-multstore
.ident "GCC: (Ubuntu 4.8.l-2ubuntul~12.04) 4.8.1"
.section .note.GNU-stack,"",©progbits
所有以'.’开头的行都是指导汇编器和链接器工作的伪指令。我们通常可以忽略这些行。另一方面,也没有关于指令的用途以及它们与源代码之间关系的解释说明。为了更清楚地说明汇编代码,我们用这样一种格式来表示汇编代码,它省略了大部分伪指令,但包括行号和解释性说明。对于我们的示例,带解释的汇编代码如下:
void multstore(long x, long y, long *dest)
x in %rdi, y in %rsi, dest in %rdx
1 multstore
2 pushq %rbx //Save %rbx
3 movq %rdx, %rbx //Copy dest to %rbx
4 call mult2 //Call mult2(x,y)
5 movq %rax, (%rbx) //Store result at *c
6 popq %rbx //Restore %rbx
7 ret
通常我们只会给出与讨论内容相关的代码行。每一行的左边都有编号供引用,右边是注释,简单地描述指令的效果以及它与原始c语言代码中的计算操作的关系。这是一种汇编语言程序员写代码的风格。
我们的表述是ATT(根据“ AT &T” 命名的,AT & T 是运营贝尔实验室多年的公司)格式的汇编代码,这是GCC、OBJDUMP 和其他一些我们使用的工具的默认格式。其他一些编程工具,包括Microsoft 的工具,以及来自Intel 的文档,其汇编代码都是Intel 格式的。这两种格式在许多方面有所不同。例如,使用下述命令行,GCC 可以产生multstore 函数的Intel 格式的代码:
linux> gcc -Og -S -masm-intel mstore.c
这个命令得到下列汇编代码:
multstore
push rbx
mov rbx, rdx
call mult2
mov QWORD PTR [rbx],
pop
ret
rbx
我们看到Intel 和ATT 格式在如下方面有所不同:
• Intel 代码省略了指示大小的后缀。我们看到指令push 和mov,而不是pushq 和movq。
• Intel 代码省略了寄存器名字前面的‘% ’符号,用的是rbx,而不是% rbx。
• Intel 代码用不同的方式来描述内存中的位置,例如是‘QWORDPTR [ rbx ] ’ 而不是' ( %rbx ) ’。
• 在带有多个操作数的指令情况下,列出操作数的顺序相反。当在两种格式之间进行转换的时候,这一点非常令人困惑。
虽然在我们的表述中不使用Intel 格式,但是在来自Intel和Microsoft 的文档中,你会遇到它。