start.S
.global _start .global _end .align 2 .text _start: b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr pc, _irq ldr pc, _fiq _undefined_instruction: .word und _software_interrupt: .word svc _prefetch_abort: .word pre_abort _data_abort: .word data_abort _not_used: .word 0x12345678 _irq: .word irq _fiq: .word fiq reset: mov ip,sp push {fp,ip,lr,pc} sub fp,ip,#4 bl clr_bss bl entry sub sp,sp,#200 sub sp,sp,#200 sub sp,sp,#200 sub sp,sp,#200 sub sp,sp,#200 sub sp,fp,#12 ldm sp,{fp,sp,pc} und: ldr sp, =0x56000000 stmfd sp!, {r0-r12, lr} mov lr, pc ldr pc, do_und_ ldmfd sp!, {r0-r12, pc}^ do_und_: .word do_und svc: stmfd sp!, {r0-r12, lr} @异常发生时arm会总动保存返回地址到lr = pc +4 sub lr, #4 @取出c程序中svc异常源的指令地址 mov r0, lr @使用r0进行参数传递 mov lr, pc ldr pc, do_svc_ ldmfd sp!, {r0-r12, pc} do_svc_: .word do_svc pre_abort: data_abort: irq: ldr sp, =0x58000000 sub lr , #4 @irq是打断正在执行的程序,因此返回必须到断点处 stmfd sp!, {r0-r12, lr} ldr r0, =0x110002e0 ldr r1, =0x1111 str r1, [r0] ldr r0, =0x110002e4 ldr r1, =0x0 str r1, [r0] mov lr, pc ldr pc, do_irq_ ldmfd sp!, {r0-r12, pc}^ do_irq_: .word do_irq fiq: .globl _bss_start _bss_start: .word __bss_start .globl _bss_end _bss_end: .word __bss_end clr_bss: mov ip, sp push {fp,ip,lr,pc} sub fp, ip, #4 ldr r0,_bss_start ldr r1,_bss_end mov r2,#0 forclrbss: cmp r0,r1 bge endclrbss strb r2,[r0],#1 b forclrbss endclrbss: sub sp, fp, #12 ldm sp, {fp, sp, pc} _end: .end
链接脚本 ld.lds
1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm","elf32-littlearm") 2 OUTPUT_ARCH(arm) 3 ENTRY(_start) 4 SECTIONS 5 { 6 /*这样可以备注吗?*/ 7 . = 0x40008000; 8 9 .text : { 10 start.o(.text); 11 *(.text); 12 } 13 14 . = ALIGN(4); 15 16 .data : { 17 *(.data); 18 } 19 20 . = ALIGN(4); 21 22 __bss_start = .; 23 .bss : { 24 *(.bss); 25 } 26 __bss_end = .; 27 }
2016-01-18