当前位置: 代码迷 >> 单片机 >> gnu arm链接的有关问题,各位大神
  详细解决方案

gnu arm链接的有关问题,各位大神

热度:110   发布时间:2016-04-28 15:12:36.0
gnu arm链接的问题,求助各位大神
这两天研究arm裸板程序,自己写了一个重定位程序,半天跑不通,最后终于解决了,但是这个问题总觉得莫名其妙,没有搞清楚为什么,所以请教下各位大神。

各位听我慢慢道来,先看代码关键部分:

copy:
ldr r0, =_start
adr r1, _start
ldr r3, =code_end
copy_loop:
ldr r4, [r1], #4
str r4, [r0], #4
cmp r0, r3
bne copy_loop
ldr pc, =led_shine

上述代码中“code_end”是从链接脚本中引入的,如下:

link.lds(全):

SECTIONS
{
   . = 0xD0024000;

   .text : {
   start.o

   }
   code_end = .;

}

链接出来后运行一直不成功,不知道怎么回事,所以我将最终生成的.bin反汇编发现如下问题

d0024060 <copy>: 
d0024060: e59f0044  ldr r0, [pc, #68] ; d00240ac  
d0024064: e24f106c  sub r1, pc, #108 ; 0x6c 
d0024068: e59f3044  ldr r3, [pc, #68] ; d00240b4 
d002406c <copy_loop>: 
d002406c: e4914004  ldr r4, [r1], #4 
d0024070: e4804004  str r4, [r0], #4 
d0024074: e1500003  cmp r0, r3 
d0024078: 1afffffb  bne d002406c <copy_loop> 
d002407c: e59ff034  ldr pc, [pc, #52] ; d00240b8  



注意上面

d0024068: e59f3044  ldr r3, [pc, #68] ; d00240b4

这句,就是对应的ldr r3, =code_end


code_end指向的地址保存在d00240b4,再看后面


d00240b0: e0200244  eor r0, r0, r4, asr #4 
d00240b4: d00240e2  andle r4, r2, r2, ror #1 
d00240b8: d002403c  andle r4, r2, ip, lsr r0



code_end指向的地址是d00240e2,居然是非4字节对齐的位置。我判断的是cmp r0, r3  bne copy_loop,是判断r0, r3是否相等。所以每次str r4, [r0], #4过后,r0加4,是不可能等于r3的(r3的值是d00240e2,因为四字节对齐,所以r0在这个值附近只会等于d00240e0, 或者d00240e4),这样就加过了,程序就跑飞了

我最后在ldr r3, =code_end后面加了一句add r3, r3, #2然后就跑通了

虽然问题解决了,但是我实在想不通这是为什么。

完全搞不懂为什么链接出来是这个样子,难道链接的时候所有的东西不是按4字节对齐的?
麻烦各位大神指导!

------解决方案--------------------
不过我倒是想起来一件事,以前做自动更新时用UltraEdit看过代码,长度的确不一定是4的整数倍
------解决方案--------------------
看看 《嵌入式Linux应用开发完全手册》 
  相关解决方案