百问网Linux技术区Linux系统开发 关于arm-linux-ld的-Ttext选项的疑问

1  /  1  页   1 跳转 查看:545

关于arm-linux-ld的-Ttext选项的疑问

关于arm-linux-ld的-Ttext选项的疑问

最近正在研读韦老师的《完全开发手册》一书,对于3.1.2arm-linux-ld选项一节,有几处疑问,百思不得其解,请各位老师指点:

1.-Ttext startadr  其中的“startadr”表示代码段。书中P40页,汇编“ldr pc, [pc,#0]”表示将当前PC寄存器的值加上偏移量0所得的地址中的值赋给PC寄存器,当arm-linux-ld的选项为-Ttext 0x30000000时,执行完该指令后,PC的值变成了0x30000008。这里的疑问是,既然-Ttext选项指定的是代码段的运行地址,那PC寄存器的值加上偏移量0所得的地址中的值,是怎样依赖于连接命令的“-Ttext”选项的呢?对照前面link_0x30000000.dis的反汇编码来看,c这个地址中的值0x30000008是怎样依赖于连接命令的“-Ttext”选项的呢?怎样理解代码段的运行地址c这个地址中的值0x30000008这种依赖关系?
2.同样在书中P40页,先使用b、b1、mov等“位置无关”的指令将代码从Flash等设备中复制到内存的“运行地址”出, 大家都知道b是跳转指令,怎样理解利用跳转指令“将代码从Flash等设备中复制到内存”中去呢?

谢谢!
 

回复:关于arm-linux-ld的-Ttext选项的疑问

1. 对于ldr pc, [pc,#0]”
  它是去一个地址取值的,这个地址是pc+0
对于Ttext 0x30000000,这个地址里面的值是0x30000008
对于Ttext 0,这个地址里面的值是0x00000008


2. 先使用b、b1、mov等“位置无关”的指令将代码从Flash等设备中复制到内存的“运行地址”;
  不是“仅仅使用跳转指令进行复制”
 

回复: 关于arm-linux-ld的-Ttext选项的疑问



引用:
原帖由 liupoldfish 于 2010-3-9 10:20:00 发表
最近正在研读韦老师的《完全开发手册》一书,对于3.1.2arm-linux-ld选项一节,有几处疑问,百思不得其解,请各位老师指点:

1.-Ttext startadr  其中的“startadr”表示代码段。书中P40页,汇编“ldr pc, [pc,#0]”表示将当前PC寄存器的值加上偏移量0所得的地址中的值赋给PC寄存器,当arm-linu





谢谢版主指点,对于第一个问题,还有一点疑问:
      如果编译程序时用-Ttext 0x30000000指定可执行文件的连接地址为0x30000000,然后将可执行文件输出为二进制文件,烧写在NAND Flash的0x00000000位置。RESET后,PC指针应该是从这段二进制代码的存储地址0x00000000开始一条一条的执行指令,每一条指令的地址相隔4字节。那这时可执行文件的连接地址又表现在哪里呢?我的理解是,只有出现与位置相关的指令时,比如ldr pc, =step1,连接地址才表现出来。
 

回复: 关于arm-linux-ld的-Ttext选项的疑问

经过看书和研究,我大概找到了问题的答案了:
      连接地址即是程序的运行地址。所谓运行地址,就是指程序运行前,这些指令必须位于内存中的这些地址上。
      连接地址为0x30000000的bin文件烧写到0x00000000的nandflash里面去,这个0x00000000就是加载地址。
      由于link.S这段代码的前面使用的是与位置无关的指令,所以即使这段代码运行前放在了0x00000000这个地址中,指令还是会被正确的执行,pc的值会偏移相对地址来找到指令。一旦使用了与位置有关的指令ldr pc, [pc, #0],pc就会去[pc, #0]取这个地址中存放的值,而这个值就是由-Ttext选项指定连接地址时,对应产生的。当pc指向连接地址上去了的时候,如果代码没有被拷贝到相应的连接地址上,那程序就不能再往下执行了,因为那里没有代码,只有烧写的地方才有代码。这也是“程序运行前,这些指令必须位于内存中的这些地址上”这句话的含义。
      感觉不太好叙述,写得比较乱,让各位看的朋友费力了
 

回复: 关于arm-linux-ld的-Ttext选项的疑问



引用:
原帖由 liupoldfish 于 2010-3-24 11:42:00 发表
经过看书和研究,我大概找到了问题的答案了:
      连接地址即是程序的运行地址。所谓运行地址,就是指程序运行前,这些指令必须位于内存中的这些地址上。
      连接地址为0x30000000的bin文件烧写到0x00000000的nandflash里面去,这个0x00000000就是加载地址。
      由于link.S这段代码的前面使用的是与位置无关的指令,所以即使这段代码运


  非常感谢你的解释,我也对于 -Ttext 参数的理解不够,因此又上网搜了下,找到了以下这个博客说明:
浅析跳转指令B和 ldr pc =label的不同
今天看了一个小程序,学习了下ARM 在裸机下的开发。学习了写东西,整理下作为笔记,程序名为link.s。
.text
.global _start
.start:
                    b  step1
step1:             
                    ldr pc, =step2
step2:
                    b step2
这个小程序使用了两种跳转方法,b 跳转指令,直接向pc 寄存器赋值。
下面进行编译,链接,反汇编,看看两者的区别:
1.arm-linux-gcc -c -o link.o  link.s
2.arm-linux-ld -Ttext 0x00000000 link.o -o link_elf_0x00000000
3.arm-linux-ld -Ttetx 0x30000000 link.o -o link_elf_0x30000000
4.arm-linux-objdump -D link_elf_0x00000000 >link_0x00000000.dis
5.arm-linux-objdump -D link_elf_0x30000000 >link_0x30000000.dis
其中4,5 两条语句用来反汇编,查看代码。
  link_0x00000000.dis文件如下:
link_elf_0x00000000:    file format elf32-littlearm
Disassembly of section .text:
00000000 <_start>:
  0: eaffffff  b 4 <step1>
00000004 <step1>:
  4: e59ff000  ldr pc, [pc, #0] ; c <step2+0x4>
00000008 <step2>:
  8: eafffffe  b 8 <step2>
  c: 00000008  andeq r0, r0, r8
link_0x30000000.dis文件如下:
link_elf_0x30000000:    file format elf32-littlearm
Disassembly of section .text:
30000000 <_start>:
30000000: eaffffff  b 30000004 <step1>
30000004 <step1>:
30000004: e59ff000  ldr pc, [pc, #0] ; 3000000c <step2+0x4>
30000008 <step2>:
30000008: eafffffe  b 30000008 <step2>
3000000c: 30000008  andcc r0, r0, r8
从link_0x00000000.dis和link_0x30000000.dis可以看出,当执行了b step1 后都跳到了step1后去执行,无论text的起始执行地址在哪,可见b跳转和PC 的位置无关,但是执行了ldr pc =step2 后,根据链接条件的不同,pc的值也会不同,link_0x00000000.dis中pc=0x000000008,link_0x30000000.dis中pc=0x30000008,这一点很重要,在bootloader中常用些与位置无关的命令,如b,bl,mov,指令将代码从flash中复制到sdram中,然后再跳到运行地址。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kwj91111/archive/2009/05/19/4202080.aspx
 
1  /  1  页   1 跳转

地址:广东省深圳市南山区南山大道3003号久商大厦C-1406;邮编:518052;电话:0755-86200561

粤ICP备09041549号, 版权所有 百问网   Sitemap

Powered by Discuz!NT 2.0.1214    Copyright © 2001-2010 Comsenz Inc.
Processed in 0.03125 second(s) , 3 queries.
返顶部