本帖最后由 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肯定就会更加狂野不羁。写书的牛人少说两句话,像我这样的蠢人就得考虑好几年啊!
|