s5pv210的学习之路(5)led.S(uboot命令调用)

abc:
mov ip,sp
stmfd sp!,{fp,ip,lr,pc}
sub fp,ip,#4

ldr r0,=led
mov lr,pc
mov pc,r0

sub sp ,fp,#12
ldmfd sp,{fp,sp,pc}

led:
mov ip,sp
sub sp,sp,#12
str r14,[sp]
str ip,[sp,#4]
str fp,[sp,#8]
sub fp,ip,#4
@ 第一步:把0x11111111写入0xE0200240(GPJ0CON)位置
ldr r0, =0x11111111 @ 从后面的=可以看出用的是ldr伪指令,因为需要编译器来判断这个数
ldr r1, =0xE0200240 @是合法立即数还是非法立即数。一般写代码都用ldr伪指令
str r0, [r1] @ 寄存器间接寻址。功能是把r0中的数写入到r1中的数为地址的内存中去
@ 第二步:把0x0写入0xE0200244(GPJ0DAT)位置
ldr r0, =0x8
ldr r1, =0xE0200244
str r0, [r1]@ 把0写入到GPJ0DAT寄存器中,引脚即输出低电平,LED点亮

ldr r0,=fmt
ldr r1,=fmt
mov r2,pc @pc作为printf第二个参数,打印出 pc=30000060 ,也即是                                               后两条,即“ldr r15,show”地址
mov r14,r15
ldr r15,show

ldr lr,[fp,#-8]
ldr ip,[fp,#-4]
ldr fp,[fp,#0]
mov sp,ip
mov r15,r14
show:
.word 0xc3e1528c @uboot的printf地址
fmt:
.asciz “hello! fmt=%p\n pc=%p\n”

编译:

arm-none-linux-gnueabi-as led.S -o led.o
arm-none-linux-gnueabi-ld -Ttext=0x30000000 led.o -o led
arm-none-linux-gnueabi-objcopy -I elf32-littlearm -O binary led /tftpboot/led.bin

uboot下下载到30000000(ddr内存)运行:
SMDKV210 jimmy# tftp 30000000 led.bin
SMDKV210 jimmy# go 30000000
显示:

Starting application at 0x30000000 …

hello! fmt=3000007c
pc=30000060 (顺带打印出pc地址看看),可以结合反汇编对比:
》arm-none-linux-gnueabi-objdump -D led.dump led|more
30000000 :
30000000: e1a0c00d mov ip, sp
30000004: e92dd800 push {fp, ip, lr, pc}
30000008: e24cb004 sub fp, ip, #4
3000000c: e59f0088 ldr r0, [pc, #136] ; 3000009c

你可能感兴趣的:(arm)