汇编文件介绍

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 的文档中,你会遇到它。