关于__user_initial_stackheap( ) |
[ 2009-10-9 0:39:00 | By:machunshui ]
|
1.作用:用于提供编译器的初始化C库函数设置用户程序的堆栈所需要的堆栈信息。 2。__user_initial_stackheap() 返回:
有单区模型和双区模型。 单区模型:(r0,r1)是单个堆栈和堆区。r1 大于 r0,并忽略 r2 和 r3。 r0--r1这一块内存区域被堆和栈共用,堆从r0向上生长,栈从r1向下生长。 双区模型:(r0, r2)是初始堆,(r3, r1) 是初始堆栈。r2 大于或等于 r0。r3 小于 r1。 堆和栈分别指定了单独的内存区域。 3.如果不使用分散加载文件,则__user_initial_stackheap()必须由用户自己实现。 实现例子: ; User Initial Stack & Heap AREA |.text|, CODE, READONLY IMPORT __use_two_region_memory EXPORT __user_initial_stackheap __user_initial_stackheap LDR R0, = Heap_Mem LDR R1, =(Stack_Mem + USR_Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR 4.使用分散加载可以由用户实现,也可以在分散加载描述文件中定义两个特殊执行区(双区模型,单区模型只定义ARM_LIB_STACKHEAP): ARM_LIB_HEAP 和 ARM_LIB_STACK(该区具有 EMPTY 属性。),从而使用C库的默认实现,此时,会导致库选择一个使用以下符号值的 __user_initial_stackheap() 实现:Image$$ARM_LIB_HEAP$$Base、Image$$ARM_LIB_HEAP$$ZI$$Limit、 Image$$ARM_LIB_STACK$$Base 和 Image$$ARM_LIB_STACK$$ZI$$Limit。这种方式比较方便。 例子: 分散加载文件: LR_IROM1 0x00000000 0x00008000 ;; Load region { ER_IROM1 0x00000000 0x00008000 { vectors.o (VECT, +First) init.o (INIT) * (+RO) } RW_IRAM1 0x40000040 0x00001460 { * (+RW,+ZI) } ;; The following declarations select the "two region model" ; ;; A default __user_initial_stackheap() will be used ; ARM_LIB_HEAP 0x40001500 EMPTY 0x00000100 {} ARM_LIB_STACK 0x40002000 EMPTY -0x00000400 {} } 在初始化文件中使用||Image$$ARM_LIB_STACK$$ZI$$Limit||作为栈底, 例子: IMPORT __use_two_region_memory IMPORT ||Image$$ARM_LIB_STACK$$ZI$$Limit|| ; Import stack limit from scatter-loading file ; ldr r1, =||Image$$ARM_LIB_STACK$$ZI$$Limit|| mrs r0,cpsr ; Original PSR value ; bic r0,r0,#MODE_BITS ; Clear the mode bits ; orr r0,r0,#IRQ_MODE ; Set IRQ mode bits ; msr cpsr_c,r0 ; Change the mode ; mov sp, r1 sub r1, r1, #IRQ_STK_SIZE ............................ |