浅谈编译器编译地址 ,cpu统一编址的物理地址,程序载入内存的地址。

来源:互联网 发布:js读取txt文件内容 编辑:程序博客网 时间:2024/06/05 16:23

随便找个IAR或者其他编译器生成的map文件。我们不难发现程序就是 .txt, .bss, .data等段的集合。

再仔细一看,BL  _main,_main是一个地址,.data段也有地址。这些地址是如何来的呢?

编译器地址空间:

编译器按照一定的地址空间来编译程序,最终的程序就是指令和地址的集合,这个地址空间就是编译器地址空间。

CPU统一寻址空间:

CPU按照统一编址的地址去访问相关数据或者硬件。

编译地址空间和物理地址空间要对上号才能正确运行。为什么呢?

如:BL _main(0x800000000). 这条是编译器编译出来指令,就是跳转到0x80000000,

假如执行完上述指令,cpu pc指针指向0x80000000,而该处没有指令,而是一个寄存器的地址,那么程序是没有办法执行的下去的。


如何实现编译地址空间和物理地址空间要对上号?
通过两种方法来实现
1:一种是编译时确定,就是给编译器设定参数比如某个段从某个地址开始编译。 

   一般如嵌入式中常见的从0x8000000, 0x2000000.或者你可以单独定义数据段从某个地址开始。

   然后通过bootloader 或者PC端载入程序把程序载入到对应的地址运行。   

   这种方式适合没有mmu的嵌入式系统的编译和载入。尤其要求载入的物理地址必须与代码段编译地址空间相对应(起始位置要相同)。


2: 通过MMU来实现地址的重定位。

    编译器不关心的物理地址,编译器把编译地址认为从0-4g进行统一编址。

    每个elf文件被载入内存,首先确定其载入内存所在的地址作为基地址,或者说将elf文件映射到对应的空间中。



0 0
原创粉丝点击