AT(ldadr):界说本段存储(加载)的地址。
看一个简略的比如:
SECTIONS{
firtst0x00000000:{head.oinit.o}
second0x30000000:AT(4096){main.o}
}
以上,head.o放在0x00000000地址开端处,init.o放在head.o后边,他们的运转地址也是0x00000000,即衔接和存储地址相同(没有AT指定);main.o放在4096(0x1000,是AT指定的,存储地址)开端处,可是它的运转地址在0x30000000,运转之前需要从0x1000(加载处)复制到0x30000000(运转处),此进程也就用到了读取Nandflash。这便是存储地址和衔接(运转)地址的不同,称为加载时域和运转时域,能够在.lds衔接脚本文件中别离指定。
编写好的.lds文件,在用arm-linux-ld衔接指令时带-Tfilename来调用履行,如arm-linux-ld–Tnand.ldsx.oy.o–oxy.o。也用-Ttext参数直接指定衔接地址,如arm-linux-ld–Ttext0x30000000x.oy.o–oxy.o。
总归:
衔接地址<==>运转地址
存储地址<==>加载地址
已然程序有了两种地址,就涉及到一些跳转指令的差异,下面就来详细看看这些跳转指令。
ARM汇编中,常有两种跳转办法:b跳转指令、ldr指令向PC赋值。
(1)bstep1:b跳转指令是相对跳转,依靠当时PC的值,偏移量是经过该指令自身的bit[23:0]算出来的,这使得运用b指令的程序不依靠于要跳到的代码的方位,只看指令自身。
(2)ldrpc,=step1:该指令是从内存中的某个方位(step1)读出数据并赋给PC,相同依靠当时PC的值,可是偏移量是那个方位(step1)的衔接地址(运转时的地址),所以能够用它实现从Flash到RAM的程序跳转。
咱们今后会经常用到“存储地址和衔接地址不同”(术语上称为加载时域和运转时域)的特性:大多机器上电时是从地址0开端运转的,可是从地址0运转程序在功能方面总有许多约束,(运转地址和加载地址不一起,只能用相对跳转)所以一般在开端的时分,运用与方位无关的指令将程序自身复制到它的衔接地址处,然后运用向pc寄存器赋值的办法跳到衔接地址开端的内存上去履行剩余的代码。
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/fpga/257345.html