arm-linux-ld实验
2012-04-23 12:06
204 查看
本文转自《S3C2410完全开发手册》
在开始后续实验之前,我们得了解一下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
6 00000000 <.data>: | 6 00000000 <.data>:
7 0: eaffffff b 0x4 | 7 0: eaffffff b 0x4
8 4: e59ff000 ldr pc, [pc, #0] ; 0xc | 8 4: e59ff000 ldr pc, [pc, #0] ; 0xc
9 8: eafffffe b 0x8 | 9 8: eafffffe b 0x8
10 c: 30000008 andcc r0, r0, r8 | 10 c: 00000008 andeq r0, r0, r8
先看看b跳转指令:它是个相对跳转指令,其机器码格式如下:
[31:28]位是条件码;[27:24]位为“1010”(0xeaffffff)时,表示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寄存器赋值的方法跳到连接地址开始的内存上去执行剩下的代码。
arm-linux-ld命令中选项“-Ttext”也可以使用选项“-Tfilexxx”来代替,在文件filexxx中,我们可以写出更复杂的参数来使用arm-linux-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
6 00000000 <.data>: | 6 00000000 <.data>:
7 0: eaffffff b 0x4 | 7 0: eaffffff b 0x4
8 4: e59ff000 ldr pc, [pc, #0] ; 0xc | 8 4: e59ff000 ldr pc, [pc, #0] ; 0xc
9 8: eafffffe b 0x8 | 9 8: eafffffe b 0x8
10 c: 30000008 andcc r0, r0, r8 | 10 c: 00000008 andeq r0, r0, r8
先看看b跳转指令:它是个相对跳转指令,其机器码格式如下:
[31:28]位是条件码;[27:24]位为“1010”(0xeaffffff)时,表示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寄存器赋值的方法跳到连接地址开始的内存上去执行剩下的代码。
arm-linux-ld命令中选项“-Ttext”也可以使用选项“-Tfilexxx”来代替,在文件filexxx中,我们可以写出更复杂的参数来使用arm-linux-ld命令
相关文章推荐
- arm-linux-gcc/ld/objcopy/objdump
- arm-linux-gcc/ld/objcopy/objdump参数总结
- arm-linux-ld命令
- u-boot移植报错:arm-linux-ld:u-boot.lds:19: syntax error
- arm-linux-ld命令 ld链接脚本
- ERROR : arm-linux-ld:u-boot.lds:1: ignoring invalid character `#' in expression
- arm-linux-ld命令 (转)
- ERROR : arm-linux-ld:u-boot.lds:1: ignoring invalid character `#' in expression
- arm-linux-ld命令
- arm-linux-ld
- 【记录】arm-linux-gcc(ld,objcopy, objbump)
- opt/FriendlyARM/toolschain/4.4.3/bin/.arm-none-linux-gnueabi-ld: cannot find -lc
- arm-linux-gcc/ld/objcopy/objdump使用总结
- arm-linux-gcc/ld/objcopy/objdump使用总结
- 【转】arm-linux-ld命令 ld链接脚本
- ARM_Linux 驱动实验项目拉力赛正式开始:
- arm-linux-ld命令
- arm-linux-ld命令
- Qemu-ARM-Ubuntu 实验二 Linux内核编译
- arm-linux-系列工具,ld,ar,as,objcopy