6410之链接地址

来源:互联网 发布:c执行多条sql语句 编辑:程序博客网 时间:2024/06/09 19:41
一个程序包括:
1.代码段 : 指令
2.数据段 : 有初始值(并且不为0)的全局静态变量

3.bss段  : 初始值为0 / 无初始值的全局静态变量


链接选项-Ttext 0
这个链接选项表示程序的代码段从0开始运行,数据段,bss段依次向后排列。
除了上面指定各个段存放位置的方法,还可以使用另外一种方法:使用链接脚本 -T leds.lds,这个链接脚本决定了各个段如何排列

例如下面的脚本就是链接脚本的格式:

SECTIONS{. = 0x50000000;    /*设置当前地址*/.text : {   /*代码段*/start.o* (.text)}    .data : {          /*数据段*/* (.data)}bss_start = .;      /*bss段*/.bss : {* (.bss)}bss_end  = .;}
引入bss_start,bss_end的原因是:编译出来的二进制文件led.bin是没有bss段(初始值为0或未初始化的全局静态变量)的。用这两个变量来给bss段清0.


如何分析反汇编文件?

先给出例子:

00000000 <_start>:       0:   e3a00207    mov r0, #1879048192 ; 0x70000000       4:   e3800013    orr r0, r0, #19       8:   ee0f0f92    mcr 15, 0, r0, cr15, cr2, {4}       c:   e59f0014    ldr r0, [pc, #20]   ; 28 <halt+0x4>      10:   e3a01000    mov r1, #0      14:   e5801000    str r1, [r0]      18:   e3a0db06    mov sp, #6144   ; 0x1800      1c:   eb000047    bl  140 <clock_init>      20:   eb000008    bl  48 <main>
第一列:地址
第二列:机器码,表示当前地址中存放的内容。
第三列:汇编代码,机器码的转换,可以被人所识别。
第四列:解析。

在不同的链接地址获取全局变量的过程

1.当链接地址为0,变量i的地址为0x100。
2.当链接地址为0x50000000,变量i的地址为0x50000100。
所以说,当链接地址不一样的话,程序访问变量的地址是不一样的。(可以实验,将链接地址改为500000000的话,DDR还没有初始化,程序就会崩溃,使用openocd的现象是无法进行halt,因为跳转到了链接地址,而DDR没有初始化。)


实验代码:

#define CONFIG_PERIPORT_BASE 0x70000000#define CONFIG_PERIPORT_SIZE 0x13#define WTCON  0x7E004000 #define GPMCON 0x7F008820#define GPMDAT 0x7F008824.global _start_start:/*告诉CPU 外设的地址*/ldr r0, =CONFIG_PERIPORT_BASEorr r0, r0, #CONFIG_PERIPORT_SIZEmcr p15,0,r0,c15,c2,4/*关闭看门狗*/ldr r0, =WTCONmov r1, #1str r1,[r0]/*点灯nLED1 <==> GPM0*//*GPMCON 0x7F008820 **GPMDAT 0x7F008824*//*设置GPM0为输出引脚*/ldr r0, =GPMCONmov r1, #0x1str r1, [r0]bl test/*ldr pc, =test */halt:b halttest:/*设置GPM0的电平输出为低,点亮*/ldr r0, =GPMDATmov r1, #0str r1, [r0]mov pc, lr
bl test的跳转:
pc 的值 == 当前的pc值 + (bl test 与 test:指令之间的偏移值)====》相对跳转

ldr pc,=test的跳转:
pc = (test:标识的链接地址),如果链接地址上没有test:指令,则就会出错  -=====> 绝对跳转

如果设置的链接地址为0x50000000,那么这个程序运行的地址也“应该”是0x50000000.但是硬件决定了如果从nand启动的话,首先运行的地址还是片内内存,因为一上电,6410 CPU 会将nandflash中的前8K内容源源本本的拷贝到6410的片内内存上去运行。那么如果想要程序在链接地址50000000上取运行,那么拷贝到片内内存上的程序需要做重定位操作。

在重定位之前的代码可以运行的原因是使用了位置无关码

位置无关码:
1.在跳转的时候使用相对跳转指令:b bl
2.不妨问全局变量,不访问静态变量

原创粉丝点击