当前位置: 首页 > news >正文

arm平台下使用bl和ldr跳转应当注意的地方(arm-linux-gcc环境)

发布时间:2008-01-02 02:23:00  来源: ChinaUnix博客    作者: ChinaUnix博客    点击:949

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 :
   0: e3a0da01  mov sp, #40Array6 ; 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: 202Array554e  eorcs r5, rArray, 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, #40Array6 ; 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: 202Array554e  eorcs r5, rArray, 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 :
       0: e3a0da01  mov sp, #40Array6 ; 0x1000
       4: e5Arrayff000  ldr pc, [pc, #0] ; 0xc
       8: eafffffe  b 0x8
       c: 30000000  andcc r0, r0, r0
...
    1000: e4d10001  ldrb r0, [r1], #1

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/33226/showart_4Array0067.html
http://www.sudu.cn/info/html/edu/20080102/282647.html
http://www.xdnf.cn/news/826489.html

相关文章:

  • WOL(Wake On LAN - 局域网唤醒)外网唤醒 配置教程 远程开机
  • Statement和PreparedStatement的区别与联系
  • pcre简介
  • 【网络安全】nmap深度入门讲解
  • 请问一下java在线编程的网站有哪一些?
  • JDK配置环境变量【图文详解】
  • 微服务网关API Geteway
  • 【Oracle database】 Oracle数据库分区表基础
  • Apriori算法详解
  • linux下logcat命令,Android logcat 命令以及 Log机制
  • 好玩的100个网站收藏
  • BDI和CDI理论四个象限的概念特点及其运用
  • MySQL中information_schema详解
  • Java 匿名内部类
  • R730结构
  • 什么是web service
  • java script 技巧_java script学习方法
  • 如何在VMware Workstation上快速构建一个windows 7虚拟机?[手把手辅导教程]
  • SQL Server中Convert函数转换日期的用法 日期格式化
  • Linux RPM包安装、卸载和升级(rpm命令)
  • python easyicon同类型ico图片批量爬取
  • Linux网络 FTP
  • 揭开pkill的秘密:在Linux中杀死进程的完整指南
  • 图解net use 命令使用示例
  • 安装最新版 MATLAB:详细安装教程
  • viewport详细讲解
  • PaddleNLP系列1-基础知识
  • Java的clientSocket
  • Docker之RUN、COMMAND、ENTRYPOINT辨析
  • Java编程技巧之样板代码