注:本文档为《从0学x86操作系统》课程配套的学习文档,提供相应的辅助学习资料和答疑勘误。 有关该课程的信息,请点击这里访问:https://study.163.com/provider/1017884735/index.htm 在阅读本文档时,如有疑问和建议,欢迎在下方留言或者直接联系我。

本课时主要介绍编译器具体如何安排工程生成的指令、数据在内存中的存储位置,并简要介绍gcc链接脚本的写法。

原理介绍

课程中通过分析工程的生成的反汇编文件和elf解析文件,展示了GCC工具链是如何安排代码、数据在内存中的存储,如下图所示。
image.png
具体而言,我们知道GCC工具链默认按.text, .rodata, .data, .bss存储代码和数据,并分析得出以下结论:

  • .text:存储机器指令和代码
  • .rodata:存储常量以及字符串本身
  • .data:存储初始化的数据,全局的或者静态的
  • .bss:存储未初始化的数据(即初始化为0),全局的或者静态的
  • stack:存储局部变量和函数调用中返回地址等
  • 相同类型的段会自动进行合并

当然,具体的细节会比上述的要复杂很多,在此我们只是得出一个初步地认识。在以后的课程中,还将会更深入其中的一些细节。我们也可以自己编写一个简单的链接脚本,来替代默认的存储配置。在链接脚本中,可以做更为复杂和灵活的设置。其语法结构为:

section { . = 虚拟地址; .text/.rodata/.data/.bss : { 目标文件(.text/.data/.bss/.data) /可使用通配符*/ }

}

扩展阅读

ARM开发中的RO, ZI, RW段

有的同学使用过arm公司的armcc工具链(如keil),其编译输出窗口中会提示RO=??, ZI=??, RW=??。

Total RO Size(Code + RO Data) 1008 ( 0.98kB) Total RW Size(RW Data + ZI Data) 96 ( 0.09kB) Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)

这三种段和上面的类似,可以理解为相同类型的段换了个名字而已:
RO:即read-only,只读,对应于.text, .rodata,因为这两者一般是不可以修改的。
RW:即read-write,可读写,对应于.data
ZI:即zero …??,初始化为0,对应于.bss

参考资料