一、前言
我们知道,如果变量和函数只声明、使用而未定义在本文件时,就属于外部引用。下面给出了两个.c文件中的代码,在main.c中声明、引用了sum.c中的sum函数,并且引用了sum.c中的全局变量gdata1。结合程序我们来对main.o和sum.o的链接过程进行分析。
//main.c
#include <stdio.h>
#include <stdlib.h>
extern int gdata1;
int sum(int,int);//外部引用
int main()
{
int num = 0;
int a = 10;
num = sum(a,gdata1);
printf("%d\n",num);
exit(0);
}
//sum.c
#include <stdio.h>
int gdata1 = 20;
int sum( int a, int b)
{
return a+b;
}
同时,我们对main.o进行分析。
$ objdump -d main.o —— 查看main.o的.text段(指令段)的反汇编代码,我们发现了一个奇怪的现象!
在传递形参gdata1时,它的地址显示为“00 00 00 00”,而调用函数sum时,它的地址则显示“ff ff ff fc”(小端),这是为什么?这是因为变量gdata1和函数sum属于外部引用,它们都定义在了sum.c文件中,只是在main.c中声明和使用了,所以单个看main.o的话,是没办法确定它们的地址的,函数printf和exit(0)调用都是在其他库中实现的,所以他俩的地址也是“ff ff ff fc”。同时,定义且使用在main.c文件中的变量a的地址则确定下来了。
我们还可以通过符号表来看;
gdata1和sum都是*UND*,也就是未定义的、未确定的。
上述我们看到了,当一个程序引用了来自其他程序的变量、函数时,它是不能独立运行的,因为这些变量和函数的地址并未确定下来。那么,对于这两个(