程序的几种常用格式文件
int global;
int calculate()
{
int a,b,c;
b=1;
return c;
}
int main()
{
calculate();
}
一、编译把每个函数翻译成可以运行的机器指令,但其中调用的函数和全局变量因为还没有分配具体的物理地址,所以会先保留其符号,main函数编译后的大致内容如下:
命令0:将内核寄存器的值压栈保存;
命令1:把global这个全局变量的值赋1;
命令2:程序跳转至函数calculate;
命令3:出栈恢复main调用者的寄存器状态,并把返回值0写入指定的寄存器中;
命令4:返回;
calculate函数编译后大致内容如下:
命令0:将内核寄存器的值压栈保存,为局部变量a、b、c分配三个寄存器用以存放其数值;
命令1:变量a置1;
命令2:变量b置1;
命令3:计算a+b,并把计算结果赋给c;
命令4:出栈恢复calculate调用者的寄存器状态,并把返回值c写入指定的寄存器中;
命令5:返回;
二、链接为所有的函数和全局变量分配一个实际的物理地址,并把编译过程中没有确定的函数和变量替换为具体的物理地址,例如可以:
把函数main的首地址安排在0x0地址上,把calculate函数的首地址安排在0x40地址上,把全局变量global安排在0x80地址上,这样main函数编译完后的命令1和命令2可以进一步改写为:
命令1(改):把地址0x80的存储内容置1;
命令2(改):程序跳转至0x40继续执行;
三、h文件头文件,
本身是不包含程序的,它的意义在于告诉要从其他.c文件调用函数的人,他所用的函数的结构是什么样子的(当然还可以定义宏、结构体等),就是一个函数的接口声明。
比如开发者完成main.c后,可以写一个main.h来告诉想调用main.c中函数的人,其函数结构是什么样子的。
四、lib文件库文件,
就是编译后,未链接的代码的集合,供其他开发者调用,通过匹配的h文件来告知开发者lib文件都有什么函数,以及这些函数的接口都是什么样子的,lib有利于程序的模块化,另外开发者不愿公开的源代码可以用lib的形式进行一定的保护(起码反汇编是件很蛋疼的事情)。
四(附)lib文件严格意义上讲叫静态库文件,所有的代码最终会在链接完成后整合成可执行文件(如.exe、.bin),但执行文件一旦生成,就与库文件没有关系了;大家可以理解为lib是房屋设计图,执行文件就是盖好的房子,房子不会因为设计图的遗失而倒塌。
五、dll文件动态链接库,
是pc中用到的,它和lib类似,也是存放函数机器码的库,但不同的是调用dll内函数的执行文件本身不包含这些函数的内容,当执行到相关的函数时,必须定位对应dll文件,将相关函数内容装载到内存中再运行;就像家里要炒个青菜,锅碗调盆都准备完了,但每次烧之前要把青菜先买回来,才能开炒。
六、o文件就是编译完后的c文件,就是一过渡文件,对编译原理不深究的人不必过多深入了解。
作者:知乎用户
链接:https://www.zhihu.com/question/20783462/answer/136827566
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。