程序员的自我修养读书笔记---编译和链接2

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。这个过程叫做重定位。重定位就是给程序中这些符号引用的地方打补丁,使得它们指向正确的地址。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值