arm-linux-ld 命令详解

本文转自《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 .text2 .global_start3 _start:4 b step15 step1:6 ldr pc,=step27 step2:8 b step2Makefile 如下:1 link:link.s2 arm-linux-gcc –c -o link.o link.s3 arm-linux-ld -Ttext 0x00000000 link.o -o link_tmp.o4 #arm-linux-ld -Ttext 0x30000000 link.o -o link_tmp.o5 arm-linux-objcopy -O binary-S link_tmp.o link6 arm-linux-objdump –D -b binary -m arm link>ttt.s7 #arm-linux-objdump –D -b binary -m arm link>ttt2.s8 clean:9 rm -f link10 rm -f link.o11 rm -f link_tmp.o实验步骤:1.进入目录LINK,运行make生成arm-linux-ld选项为“-Ttext 0x00000000”的反汇编码ttt.s2.make clean3.修改Makefile:将第4、7行的“#”去掉,在第3、6行前加上“#”4.运行make生成arm-linux-ld选项为“-Ttext 0x30000000”的反汇编码ttt2.slink.s程序中用到两种跳转方法:b跳转指令、直接向pc寄存器赋值。我们先把在不同“—Ttext”选项下,生成的可执行文件的反汇编码列出来,再详细分析这两种不同指令带来的差异。ttt.s:ttt2.s6 00000000 <.data>: | 6 00000000 <.data>:7 0: eaffffff b 0x4 | 7 0: eaffffff b 0x48 4: e59ff000 ldr pc, [pc, #0] ; 0xc | 8 4: e59ff000 ldr pc, [pc, #0] ; 0xc9 8: eafffffe b 0x8 | 9 8: eafffffe b 0x810 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得到:0xffffffff2.将此32位数左移两位得到:0xfffffffc,其值就是-43.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 命令详解

相关文章:

你感兴趣的文章:

标签云: