打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
操作系统学习之程序编译,链接,加载过程中的内存管理

程序从代码到可执行程序的过程:

代码-编译-链接-加载-执行

编译:编译器将源程序转换成可重定位代码。其有三个逻辑地址块:代码段(机器指令块),数据段(静态变量块),栈段(表示程序执行时使用的栈)。

编译器将所有的翻译过的机器指令写入代码段。考虑可重定位对象模块中的过程入口点,一般而言,编译器不能确定入口点的地址,因为目标过程可能在不同的可重定位模块中。例如,如果目标是库例程,如printf(),目标函数在系统软件建立时就编译好了。由于在编译时不知道目标模块的地址,所以目标函数不能被绑定,知道连接器将调用函数的模板与定义函数的模版链接为止。编译器将注明对每个外部地址的引用,使得链接器在链接时可以确定在绝对程序中外部引用的地址,并能将正确的地址填入代码中。

现在考虑静态变量在源程序中是如何处理的。(即使静态变量出了作用域,它仍保持最后一次存储的值)在编译时,编译程序生成代码在数据段为静态变量分配存储位置,然后指令中使用数据段中的相对地址引用变量。但是如果一个C语言的自动变量,编译器会产生代码在运行时栈中回到作用域,它不会保持旧的值。自动变量的存储空间会在程序执行时动态创建和释放,所以编译器会产生相对于栈的底部(而不是数据段地址)的变量指针。

链接:在链接时,每个可重定位对象模块的代码和数据段联合形成绝对程序。链接器会将所有的数据段联合成单个的数据段,并将所有的代码段联合成单个代码段。当数据段合并时,各静态变量的相对地址将改变。链接器然后重定位指令中的地址,使得它们引用合并的数据段中的新地址。链接器然后对入口点引用与合并代码段中定义的入口点地址进行匹配。在合并可重定位模块时,所有未定义的地址引用最后会被链接器发现,最终的组合模块包括了所有的程序文本和数据,这样每个数据的引用或程序入口点的引用都被解决了。绝对模块可以存储在文件(辅存)直到被执行。

加载:在加载一个绝对程序之前,存储管理器会分配一块主存给进程。然后加载器会将绝对程序和数据拷贝到分配的存储器中。注意,绝对模块的代码段部分中的地址需要再次调整。链接器将绝对程序中的所有地址设置成好像模块是从主存位置0处加载的。然而,模块现在是主存中的一个特定物理地址被加载的:存储块汇总的首地址需要由存储管理器指定。加载器转换每个内部逻辑主地址,使得它引用的是被分配的主存地址(而不是数据段或代码段的偏移量)。将程序使用的地址与主存中的物理存储位置相关联的过程称为地址绑定。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
DLL基础
code guy的自我修养 | 隨緣
计算机大佬让你彻底了解深入理解计算机系统
编译与链接
uboot编译连接脚本文件uboot.lds
C语言内存中执行外部代码详解(一) | Hoverlees' Blog
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服