位置无关码,位置有关码,运行地址,加载地址, 实际加载地址

运行地址:链接时指定的连接地址,计算机认为程序运行时应该处于的地址,程序代码的地址是以运行地址来表示的,在编译时,编译器根据运行地址来翻译位置有关码。

加载地址:链接指定存放在编译所得镜像文件的地址,默认等于运行地址。

位置无关码:依赖于程序当前运行的PC值,进行相对的跳转。无论代码在哪,总能达到指令的正常目的,因此是位置无关的。

位置有关码:不依赖当前PC值,是绝对跳转,只有程序运行在链接地址处时,才能达到指令的正常目的,因此是位置有关系的。

下面,我们来看常用的汇编指令哪些是位置有关码,哪些是位置无关码。

b main              /*相对跳转,位置无关*/
bl main             /*相对跳转,位置无关*/

adr r0, main      /* 获取标号地址(相对),位置无关

ldr r0, _start      /* 获取标号地址(相对)处的值,位置无关 */

ldr r0, =_start   /* 获取标号地址(绝对),位置有关 */

加载时域与运行时域:可以这么理解,加载时域涉及到存储地址;运行时域涉及到连接地址(连接地址开始作用的时间是在使用伪指令ldr(adr、adrl)pc,=某符号或是某立即数时)。可执行程序在被下载到相应存储器件里时,它的存储地址可以通过oflash来选择;而当运行该程序时,一开始时PC寄存器的值是指向存储空间的起始地址(起始地址由oflash决定)的,但在遇到伪指令ldr(adr、adrl)pc,=某符号或是某立即数(位置无关相对跳转指令B与BL不影响运行地址)后,程序运行时的绝对地址(即PC寄存器的值)就发生了改变,它是以连接地址(由arm-linux-ld之-T选项设定)为基址,指令所在位置为相对地址共同组成的。

总之:运行地址=-T指定的连接地址+相对偏移地址;存储地址=由oflash指定某存储器件的起始地址+由链接文件中AT指定的加载地址。

关于位置无关码,位置有关码,运行地址,加载地址的概念不多说,结尾链接里的几篇文章说的很清楚,这里主要讲下实际加载地址:

关于实际加载地址:

1.链接脚本中定义的段没有包含所有的程序时,那么剩下的程序会被依次放在定义的段的运行地址的后面。

2.当连接脚本中指定了多个段时,如果所有段的最小的加载地址大于0,那么链接过程中链接器会把所有段的加载地址减去这个最小的加载地址,使得最小加载地址为0(从编译所得镜像文件的0地址开始存放),得到的才是实际加载地址。

下面举例说明:

假设a.o占256 byte, b.o占512 byte,

Makefile部分代码:

arm-linux-ld -Ttest.lds a.o b.o -o test_elf

arm-linux-objcopy -O binary -S test_elf test.bin

例1:

test.lds:

SECTIONS{

first   0x30000000  :  {a.o}

}

a.o的加载地址=运行地址=0x30000000, b.o的运行地址和加载地址都为0x30000100,

最小加载地址为0x30000000,大于0,那么a.o的实际加载地址为0,从test.bin的起始地址开始存储,b.o实际加载地址为0x100, test.bin大小为256+512=768byte;

例2:

test.lds:

SECTIONS{

first   0x30000000  :  AT(0) {a.o}

}

a.o运行地址指定为0x30000000,加载地址指定为0,则b.o 运行地址和加载地址都为为0x30000100,此时所有段最小加载地址为0,那么实际加载地址等于设定的加载地址,test.bin 大小为 0x30000100 + 0x200 = 0x30000300

例3:

test.lds:

SECTIONS{

first         0x30000000  :  AT(0x30000000)  {a.o }

second   0x30000100 :   AT(0x10000000)  {b.o}

}

最小加载地址为0x10000000,那么b.o 的实际加载地址为0,a.o的实际加载地址为0x30000000 - 0x10000000 = 0x20000000,

此时test.bin 的大小为 0x20000000 + 0x100 = 0x20000100;

例4:

test.lds:

SECTIONS{

first   0x30000000  :   {a.o b.o}

}

所有的程序都在一个段中,这时候无论加载地址指定为多少,加载时都会把这个段放在test.bin的起始位置,即实际加载地址为0.

链接:

https://www.cnblogs.com/control-exe/p/6707960.html

https://blog.csdn.net/lin111000713/article/details/38583117

https://blog.csdn.net/lizuobin2/article/details/52049892

猜你喜欢

转载自blog.csdn.net/z1026544682/article/details/82820076