博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

嵌入式linux

构建完善的嵌入式linux平台
   uClinux.cublog.cn
关于作者  
姓名:panhuachun@hotmail.com
职业:软件工程师
年龄:24
位置:China
个性介绍:构建优美的嵌入式平台

我的分类  




arm平台下使用bl和ldr跳转应当注意的地方(arm-linux-gcc环境)
    
     arm平台下使用bl和ldr跳转应当注意的地方(arm-linux-gcc环境)
         作者 :  MSN:panhuachun@hotmail.com

一,按lds文件连接的不同模块,不能用bl实现跳转

一个错误的例子:
1.crt0.s
@******************************************************************************
@ File:crt0.s
@ 功能:通过它转入C程序
@******************************************************************************      
.extern  main
.text
.global _start
_start:
    ldr  sp, =1024*4 @设置堆栈,注意:不能大于4k ,
        @这儿堆栈可以设置为0x34000000,根据内存地址空间分配确定
        
   bl  main         @调用C程序中的main函数
halt_loop:
   b  halt_loop
 
2.leds.c
@******************************************************************************
@ file leds.c
@ main函数
@******************************************************************************   
int main()
{
       __asm__
       ( 
             " ldrb  r0, [r1], #1\n"
             " strb  r0, [r2], #1\n"
       );
 return 0;
}
 
3.Makefile
CFLAGS  := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding -c
leds : crt0.s  leds.c
 arm-linux-gcc $(CFLAGS) -o crt0.o crt0.s
 arm-linux-gcc $(CFLAGS) -o leds.o leds.c
 arm-linux-ld -Tleds.lds  crt0.o leds.o -o leds_tmp.o
 arm-linux-objcopy -O binary -S leds_tmp.o leds
 arm-linux-objdump -D -b binary -m arm  leds >ttt.s
clean:
 rm -f   leds
 rm -f   leds.o
 rm -f   leds_tmp.o
 rm -f   crt0.o

4.leds.lds 文件
SECTIONS {
  firtst   0x00000000 : { crt0.o }
  second  0x00000000 :  AT(0x0100) { leds.o }
}

5.反汇编代码ttt.s
00000000 <.data>:
   0: e3a0da01  mov sp, #4096 ; 0x1000
   4: ebfffffd  bl 0x0                      //这儿不能调转到main 因为bl跳转有限制
   8: eafffffe  b 0x8
 ...
 100: e24dd040  sub sp, sp, #64 ; 0x40
 104: e3a00000  mov r0, #0 ; 0x0
 108: e28dd040  add sp, sp, #64 ; 0x40
 10c: e1a0f00e  mov pc, lr
 110: 43434700  cmpmi r3, #0 ; 0x0
 114: 4728203a  undefined
 118: 2029554e  eorcs r5, r9, lr, asr #10
 11c: 2e332e33  mrccs 14, 1, r2, cr3, cr3, {1}
 120: 00000032  andeq r0, r0, r2, lsr r0
通过上面的例子可以看到crt0中的bl main出错
"4: ebfffffd  bl 0x0   "
bl没有成功。                  

6.改正方法1:
原lds文件把俩个目标文件分开排列,这里把俩个目标文件指定到一起,这样不能重定位。
修改后的lds文件
SECTIONS {
  firtst   0x00000000 : { crt0.o leds.o  }
 
}
改正后的效果
    0: e3a0da01  mov sp, #4096 ; 0x1000
   4: eb000000  bl 0xc                  //这里bl跳转到正确的地址
   8: eafffffe  b 0x8
   c: e24dd040  sub sp, sp, #64 ; 0x40
  10: e3a00000  mov r0, #0 ; 0x0
  14: e28dd040  add sp, sp, #64 ; 0x40
  18: e1a0f00e  mov pc, lr
  1c: 43434700  cmpmi r3, #0 ; 0x0
  20: 4728203a  undefined
  24: 2029554e  eorcs r5, r9, lr, asr #10
  28: 2e332e33  mrccs 14, 1, r2, cr3, cr3, {1}
  2c: 00000032  andeq r0, r0, r2, lsr r0
 

二,使用ldr命令来实现长跳转(改正方法2)
1.
ldr pc,      =main  @调用C程序中的main函数
通过ldr 对pc赋值来实现跳转
@******************************************************************************
@ File:crt0.s
@ 功能:通过它转入C程序
@******************************************************************************      
.extern  main
.text
.global _start
_start:
    ldr  sp, =1024*4 @设置堆栈,注意:不能大于4k,nand flash中的代码在复位后会移到内部ram中,此ram只有4k
   ldr pc,      =main  @调用C程序中的main函数
halt_loop:
   b  halt_loop
2.leds.lds文件
SECTIONS {
  firtst   0x00000000 : { crt0.o }
  second  0x30000000 :  AT(0x1000) { leds.o }
}
 
3.反汇编结果
00000000 <.data>:
       0: e3a0da01  mov sp, #4096 ; 0x1000
       4: e59ff000  ldr pc, [pc, #0] ; 0xc
       8: eafffffe  b 0x8
       c: 30000000  andcc r0, r0, r0
 ...
    1000: e4d10001  ldrb r0, [r1], #1
    1004: e4c20001  strb r0, [r2], #1
    1008: e3a00000  mov r0, #0 ; 0x0
    100c: e1a0f00e  mov pc, lr
    1010: 43434700  cmpmi r3, #0 ; 0x0
    1014: 4728203a  undefined
    1018: 2029554e  eorcs r5, r9, lr, asr #10
    101c: 2e332e33  mrccs 14, 1, r2, cr3, cr3, {1}
    1020: 00000032  andeq r0, r0, r2, lsr r0
可以看到4: e59ff000  ldr pc, [pc, #0] ; 0xc
这条命令将跳转到0x30000000处开始执行

 发表于: 2008-03-05,修改于: 2008-03-22 13:41 已浏览238次,有评论3条 推荐 投诉

  网友评论
  本站网友 时间:2008-03-19 20:26:57 IP地址:222.179.100.★
你好,
我遇到一个问题,就是在汇编文件中不能识别用.global定义的全局变量,编译的时候编译器总是报错global前面的点,这些特殊的符号好像不属于arm的汇编怎样解决,麻烦指点一下。

  panhuachun 时间:2008-03-20 18:08:05 IP地址:124.129.79.★
我这个是gcc环境,你用的是什么环境的啊?ads和着个有差别

  本站网友 时间:2008-03-22 17:29:30 IP地址:222.179.100.★
是gcc环境,用的编译器是arm-elf-gcc等编译工具,就是总是报错,连接脚本里的就没错,可就是到汇编语言中就不对了,这种格式好像不属于arm汇编,应该怎样解决,是不是缺少什么编译选项。。。。


  发表评论



Copyright © 2001-2006 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们
页面生成时间:0.01836

京ICP证041476号