概述
1- P38 一个c代码如何编译成可执行文件
xx.c+xx.h--->预编译xx.i--->编译成xxx.asm--->汇编成xxx.o+xxx.a--->链接成xxx.out
2- P41 编译器做了什么
3- P48链接器诞生的背景(重点阅读)
原始的程序员将程序记录在打点的纸带上,纸带上每一行的孔可以理解成某个物理地址处的指令。
场景: 我们在执行纸带第一行的指令,假定第一行的指令表示要跳到第5行去执行另一条指令。
如果我们发现代码有bug,需要在第3行添加两行打孔。这样我们就得修改第一行打孔,让其跳转到第7行去执行指令。
这样每一增删代码,都需要重新计算跳转指令的地址(重定位)。
为了解决每次增删代码需要重新计算跳转代码的地址这个问题,引入汇编代码。
汇编代码以符号助记,比如我们想要跳转到foo处,汇编码表示为:
jmp foo
如果修改了汇编代码,重新汇编后都会计算出foo的地址。我们只需要使用foo这个符号,而不用计算foo地址。
所以纸带以行数表示函数、变量的初始地址,汇编代码以符号表示函数、变量地址的初始地址。
随着程序量不断增大,我们的代码以模块划分。模块间、模块内符号引用时 ,我们如何确定符号的地址?
模块单独编译时,我们能够计算出模块内的符号相对于模块初始的地址。
为了计算模块间符号引用时符号的地址,需要把模块拼接起来。这样模块的拼接顺序固定了,各模块的符号地址也就确定了,这样就解决了模块符号引用(符号地址确定)的问题。
链接就是用于把不同的模块拼接起来。
链接的作用和程序员人工调整地址没有什么本质差别。
4- P50 模块拼接--静态链接(重点阅读)
场景: 我们编译出两个目标文件:a.o和b.o。有一个变量var定义在a.o中,在b.o中操作var变量。
#b.o中操作var变量,令var=1
mov1 $0x01, var
由于b.o中不知道var变量的地址是多少,暂定将其地址认为是0x0000 0000。等链接器链接a.o、b.o后,我们知道var符号的地址为0x1000 0000,我们重新修正mov指令中var变量的地址为0x1000 0000。这个过程叫做重定位。重定位就是给程序中这些符号引用的地方打补丁,使得它们指向正确的地址。
最后
以上就是无私枫叶为你收集整理的程序员的自我修养读书笔记---编译和链接21- P38 一个c代码如何编译成可执行文件2- P41 编译器做了什么3- P48链接器诞生的背景(重点阅读)4- P50 模块拼接--静态链接(重点阅读)的全部内容,希望文章能够帮你解决程序员的自我修养读书笔记---编译和链接21- P38 一个c代码如何编译成可执行文件2- P41 编译器做了什么3- P48链接器诞生的背景(重点阅读)4- P50 模块拼接--静态链接(重点阅读)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复