我是靠谱客的博主 无私枫叶,最近开发中收集的这篇文章主要介绍程序员的自我修养读书笔记---编译和链接21- P38 一个c代码如何编译成可执行文件2- P41 编译器做了什么3- P48链接器诞生的背景(重点阅读)4- P50 模块拼接--静态链接(重点阅读),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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 模块拼接--静态链接(重点阅读)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部