编译生成的文件是1定格式的,里面包括函数符号表、参数表...等信息,这些信息主要是提供给链接阶段使用,函数调用是怎样调用的?是否是指定利用的函数的符号?所以链接阶段就是将函数调用的符号变成相对地址(要特别注意这个阶段,由于这个进程使得C语言和汇编语言相互调用成为可能)。
既然都生成了相同格式的.o中间文件,那末ld链接器便可将两个中间文件链接成为2进制可履行文件了,ld主要做的工作是将bar.o foo.o中的相互援用的函数符号变成在2进制文件foobar中相对地址(相对地址在2进制文件装入内存运行的时候会被全部转换为绝对地址)
进程如图所示:
foo.asm
extern choose;
[section .data]
num1st dq 3
num2nd dq 4
[section .text]
global main
global myprint
main:
push qword [num2nd]
push qword [num1st]
call choose
add esp,8
mov ebx,0
mov eax,1
int 0x80
; pop qword [num1st]
; pop qword [num2nd]
myprint:
mov edx,[esp+8]
mov ecx,[esp+4]
mov ebx,1
mov eax,4
int 0x80
; pop qword [num1st]
; pop qword [num2nd]
ret
bar.c
void myprint(char * msg,int len);
int choose(int a,int b)
{
if (a>=b){
myprint("the 1st one
",13);}
else {
myprint("the 2nd one
",13);}
return 0;
}