1.代码示例
假设我们写了一个C语言代码文件mstore.c:
long mult2(long,long);
void multstore(long x, long y, long *dest){
long t = mult2(x,y);
*dest = t;
}
然后运行如下命令(-S选项可以查看C语言编译器产生的汇编代码,-Og是进行最小优化):
gcc -Og -S mstore.c
会得到一个汇编文件mstore.s,但是不进行其他操作(正常会继续调用汇编器产生目标代码)。
包括了以下几行:
multstore:
pushq %rbx
movq %rdx, %rbx
call mult2@PLT
movq %rax, (%rbx)
popq %rbx
ret
上述代码每一个缩进的行对应一条机器指令。
然后运行-c选项,GCC会编译并汇编该代码,得到目标文件mstore.o,由于是二进制格式,无法直接查看:
gcc -Og -c mstore.c
反汇编:
objdump -d mstore.o
得到结果如下:
18个字节,分别对应了右边的汇编指令
生成 实际可执行文件的代码需要对一组目标代码文件运行链接器,而这一组目标代码文件中必须包含一个main函数,假设main.c有下面这样的函数。
#include <stdio.h>
void multstore(long, long, long *);
int main() {
long d;
multstore(2, 3, &d);
printf("2 * 3 --> %ld \n", d);
return 0;
}
long mult2(long a, long b) {
long s = a * b;
return s;
}
然后生成可执行文件prog:
gcc -Og -o prog main.c mstore.c
也可以反汇编prog文件:
objdump -d prog
可以看到,主要是 左侧 的地址不同,这是因为链接器将这段代码的地址移动到了一段不同的地址范围中,第二个不同之处在于链接器填上了callq指令调用函数mult2需要使用的地址。