本帖最后由 xinzha 于 2009-9-6 14:21 编辑
一段汇编
; On reset, an aliased copy of ROM is at 0x0.
LDR pc, =Instruct_2
Instruct_2
; Remap by setting Remap bit of the CM_ctl register
LDR r1, =CM_ctl_reg
LDR r0, [r1]
ORR r0, r0, #Remap_bit
STR r0, [r1]
; RAM is now at 0x0.
; The exception vectors (in vectors.s) must be copied from ROM to the RAM
; The copying is done later by the C library code inside __main
ENDIF
;EXPORT Reset_Handler
Reset_Handler
; --- Initialize stack pointer registers
; Enter each mode in turn and set up the stack pointer
IMPORT top_of_stacks ; defined in stack.s and located by scatter file
LDR r0, =top_of_stacks
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; No interrupts
SUB sp, r0, #Offset_FIQ_Stack
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
SUB sp, r0, #Offset_IRQ_Stack
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit ; No interrupts
SUB sp, r0, #Offset_ABT_Stack
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit ; No interrupts
SUB sp, r0, #Offset_UND_Stack
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
SUB sp, r0, #Offset_SVC_Stack
; --- Now change to User mode and set up User mode stack, if needed
MSR CPSR_c, #Mode_USR:OR:I_Bit:OR:F_Bit ; No interrupts
SUB sp, r0, #Offset_USR_Stack
IMPORT main
; --- Now enter C code
B main ; note use B not BL, because an application will never return this way
这段代码一定都很熟悉,它存在于很多arm芯片的参考设计中,在这段代码中清晰地体现出来地址重映射以及栈初始化的过程, B main这句之后就跳转到大家更熟悉的c代码中。过去看书的时候经常看到这样一句“在进行cpu的初始化之后,就可以执行c代码”,我觉得这里应该多说两句,因为我当时死活想不明白,不都是编译成了跟机器码一一对应的汇编,咋对cpu来说c和汇编还有差别?后来才渐渐知道原来是因为c编译器在处理c代码的时候需要栈的协助,如果此时栈寄存器没有初始化,那么这里面的栈指针是野,后面的c肯定就会更加狂野不羁。写书的牛人少说两句话,像我这样的蠢人就得考虑好几年啊! |