6410之链接地址
来源:互联网 发布:c执行多条sql语句 编辑:程序博客网 时间:2024/06/09 19:41
一个程序包括:
1.代码段 : 指令
2.数据段 : 有初始值(并且不为0)的全局静态变量
第二列:机器码,表示当前地址中存放的内容。
第三列:汇编代码,机器码的转换,可以被人所识别。
第四列:解析。
在不同的链接地址获取全局变量的过程:
pc 的值 == 当前的pc值 + (bl test 与 test:指令之间的偏移值)====》相对跳转
而
ldr pc,=test的跳转:
pc = (test:标识的链接地址),如果链接地址上没有test:指令,则就会出错 -=====> 绝对跳转
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, lrbl 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.不妨问全局变量,不访问静态变量
- 6410之链接地址
- tiny6410裸机程序之四、链接地址
- 链接地址
- 链接地址
- 链接地址
- 链接地址
- 链接地址
- 链接地址,加载地址
- 编译链接之----地址无关代码(PIC)总结
- 链接地址和存储地址
- 链接地址与存储地址
- 加载地址和链接地址
- u-boo学习记录之最后的链接命令分析,以及链接地址存放在何处
- 常用地址链接
- Java开发链接地址
- Blog链接地址:)
- 资料的链接地址
- js获取链接地址
- oracle sql优化一(转载)
- Filter过滤器+Cookie机制实现网站访问量统计
- linux命令(21):find命令之xargs
- Table之CSS控制Table内外边框,颜色,大小
- 黑马程序员-异常
- 6410之链接地址
- 底部导航的RadioButton 方式实现
- linux命令(22):find 命令的参数详解
- 通过软件架构来达到易用性-易用性的好处
- POJ 1274 匈牙利算法
- SQL中的INNER JOIN和JOIN有什么区别
- android 读取assets下的文件
- Oracle基本SQL语句
- 无限极分类php实现—查子孙树、家谱树