您的位置:首页 > 运维架构 > Linux

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

2015-05-20 15:05 1071 查看


发布时间: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐