arm-linux-ld lds脚本文件
来源:互联网 发布:phxsql mysql 5.7 编辑:程序博客网 时间:2024/05/17 08:35
arm-linux-ld
1:b和ld的差异
在开始后续实验之前,我们得了解一下arm-linux-ld连接命令的使用。在
上述实验中,我们一直使用类似如下的命令进行连接:
arm-linux-ld -Ttext 0x00000000 crt0.o led_on_c.o -o led_on_c_tmp.o
我们看看它是什么意思:-o选项设置输出文件的名字为 led_on_c_tmp.o;
“--Ttext 0x00000000”设置代码段的起始地址为0x00000000;这条指令的作用就
是将crt0.o和led_on_c.o连接成led_on_c_mp.o可执行文件,此可执行文件的代
码段起始地址为0x00000000。
我们感兴趣的就是“—Ttext”选项!进入LINK目录,link.s代码如下:
1 .text
2 .global _start
3 _start:
4 b step1
5 step1:
6 ldr pc, =step2
7 step2:
8 b step2
Makefile如下:
1 link:link.s
2 arm-linux-gcc -c -o link.o link.s
3 arm-linux-ld -Ttext 0x00000000 link.o -o link_tmp.o
4 # arm-linux-ld -Ttext 0x30000000 link.o -o link_tmp.o
5 arm-linux-objcopy -O binary -S link_tmp.o link
6 arm-linux-objdump -D -b binary -m arm link >ttt.s
7 # arm-linux-objdump -D -b binary -m arm link >ttt2.s
8 clean:
9 rm -f link
10 rm -f link.o
11 rm -f link_tmp.o
实验步骤:
1.进入目录LINK,运行make生成arm-linux-ld选项为“-Ttext 0x00000000”
的反汇编码ttt.s
2.make clean
3.修改Makefile:将第4、7行的“#”去掉,在第3、6行前加上“#”
4.运行make生成arm-linux-ld选项为“-Ttext 0x30000000”的反汇编码ttt2.s
link.s程序中用到两种跳转方法:b跳转指令、直接向pc寄存器赋值。我们先
把在不同“—Ttext”选项下,生成的可执行文件的反汇编码列出来,再详细分析这
两种不同指令带来的差异。
ttt.s: ttt2.s
0: eaffffff b 0x4 0: eaffffff b 0x4
4: e59ff000 ldr pc, [pc, #0] ; 0xc 4: e59ff000 ldr pc, [pc, #0] ; 0xc
8: eafffffe b 0x8 8: eafffffe b 0x8
c: 00000008 andeq r0, r0, r8 c: 30000008 tsteq r0, #8 ; 0x8
先看看 b 跳转指令:它是个相对跳转指令,其机器码格式如下:
[31:28]位是条件码;[27:24]位为“1010”时,表示 B 跳转指令,为“1011”时,表示 BL
跳转指令;[23:0]表示偏移地址。使用 B 或BL 跳转时,下一条指令的地址是这样计算的:将指
令中 24 位带符号的补码立即数扩展为 32(扩展其符号位);将此 32 位数左移两位;将得到的值
加到 pc 寄存器中, 即得到跳转的目标地址。 我们看看第一条指令 “b step1” 的机器码 eaffffff:
1. 24 位带符号的补码为 0xffffff,将它扩展为 32 得到:0xffffffff
2.将此 32 位数左移两位得到:0xfffffffc,其值就是-4
3.pc 的值是当前指令的下两条指令的地址,加上步骤 2 得到的-4,这恰好是第
二条指令step1 的地址
各位不要被被反汇编代码中的“b 0x4”给迷惑了,它可不是说跳到绝对地址 0x4
处执行,绝对地址得像上述 3 个步骤那样计算。您可以看到 b 跳转指令是依赖于当
前 pc 寄存器的值的, 这个特性使得使用b 指令的程序不依赖于代码存储的位置——
即不管我们连接命令中“--Ttext”为何,都可正确运行。
再看看第二条指令ldr pc, =step2:从反汇编码“ldr pc, [pc, #0]”可以看出,
这条指令从内存中某个位置读出数据,并赋给 pc 寄存器。这个位置的地址是当前
pc 寄存器的值加上偏移值 0,其中存放的值依赖于连接命令中的“--Ttext”选项。
执行这条指令后,对于 ttt.s,pc=0x00000008;对于 ttt2.s, pc=0x30000008。于
是执行第三条指令“b step2”时,它的绝对地址就不同了:对于ttt.s,绝对地址
为 0x00000008;对于 ttt.s,绝对地址为0x30000008。
ttt2.s 上电后存放的位置也是 0,但是它连接的地址是 0x30000000。我们以后
会经常用到“存储地址和连接地址不同”(术语上称为加载时域和运行时域)的特性:
大多机器上电时是从地址 0 开始运行的,但是从地址 0 运行程序在性能方面总有很
多限制,所以一般在开始的时候,使用与位置无关的指令将程序本身复制到它的连
接地址处, 然后使用向pc 寄存器赋值的方法跳到连接地址开始的内存上去执行剩下
的代码。在实验 5、6 中,我们将会作进一步介绍。
arm-linux-ld 命令中选项“-Ttext”也可以使用选项“-Tfilexxx”来代替,在
文件 filexxx中, 我们可以写出更复杂的参数来使用 arm-linux-ld 命令——在实验
6 中,我们就是使用这种方法来指定连接参数的。
2:lds脚本文件
1 SECTIONS {
2 firtst 0x00000000 : { head.o init.o }
3 second 0x30000000 : AT(4096) { main.o }
4 }
完整的连接脚本文件形式如下:
SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
{ contents } >region :phdr =fill
...
}
并非每个选项都是必须的,仅介绍nand.lds用到的:
1、secname:段名,对于nand.lds,段名为first和second
2、start:本段运行时的地址,如果没有使用AT(xxx),则本段存储的地址
也是start
3、AT( ldadr ):定义本段存储(加载)的地址
4、{ contents }:决定哪些内容放在本段,可以是整个目标文件,也可以
是目标文件中的某段(代码段、数据段等)
nand.lds的含义是:head.o放在0x00000000地址开始处,init.o放在hean.o
后面,它们的运行地址是0x00000000;main.o放在地址4096(0x1000)开始处,但
是它的运行地址在0x30000000,在运行前需要从4096处复制到0x30000000处。为
了更形象一点,您可以打开反汇编文件ttt.s,现摘取部分内容如下:
00000000 <.data>:
1 0: e3a0da01 mov sp, #4096 ; 0x1000
2 4: eb00000b bl 0x38
3 8: eb000011 bl 0x54
4 c: eb000042 bl 0x11c
...
5 1000: e1a0c00d mov ip, sp
6 1004: e92dd800 stmdb sp!, {fp, ip, lr, pc}
7 1008: e24cb004 sub fp, ip, #4 ; 0x4
8 100c: e59f1058 ldr r1, [pc, #88] ; 0x106c
...
上面的第1-4行与head.s中的前面4行代码对应,第2-4行调用init.c中的函
数disable_watch_dog、memsetup、init_nand;再看看第5行,“1000”的得来
正是由于设置了“AT(4096)”,这行开始的是main.c中的第一个函数Rand()。
如果您想进一步了解连接脚本如何编写,请参考《Using ld The GNU linker》
(在目录“参考资料”下)。
- arm-linux-ld lds脚本文件
- arm-linux-ld命令 ld链接脚本(不错,推荐可以学习一些lds链接脚本文件)
- arm-linux-ld命令 ld链接脚本
- arm-linux-ld命令 ld链接脚本
- arm-linux-ld命令 ld链接脚本
- arm-linux-ld 连接脚本问题
- ld选项和lds文件
- 【转】arm-linux-ld命令 ld链接脚本
- 【转】arm-linux-ld命令 ld链接脚本
- ARM学习笔记020之LDS脚本链接文件
- GCC-LD 连接脚本分析--uboot.lds
- GNU ld链接脚本lds简单教程
- 链接器ld和链接脚本lds
- GCC-LD 连接脚本分析--uboot.lds
- u-boot移植报错:arm-linux-ld:u-boot.lds:19: syntax error
- ERROR : arm-linux-ld:u-boot.lds:1: ignoring invalid character `#' in expression
- ERROR : arm-linux-ld:u-boot.lds:1: ignoring invalid character `#' in expression
- ERROR : arm-linux-ld:u-boot.lds:1: ignoring invalid character `#' in expression
- ibatis 的批量插入 批量更新数据
- [SQL server] 取得表中有默认值的字段名及默认值(几个系统表的应用)
- ExtJS4新发现07_监听键盘事件
- 用C读取INI配置文件
- 注册机使用方法
- arm-linux-ld lds脚本文件
- 红黑树(Red Black Tree)
- Exchange 2010 sp2使用脱机地址簿策略隔离用户访问!
- Sublime Text 2 使用以及破解
- 使用lacewing解决HTTP+XML接口问题
- 毛路:有些事,让别人相信就行了
- ExtJS4新发现08_改变字体大小提示
- Hadoop体系结构指南
- 快速学习html、css的经典笔记(不看后悔偶)