在sam7x的启动代码里面我看到开了三个栈,svc irq 和usr,各256字节。但是在最后的这里有个问题,红色的字是被注掉了,原先这里要进入usr模式设置sp寄存器的,现在停留在svc模式,但是下面的sp设置却保留了,也就是说设置了两次svc的sp,后一次指向usr模式栈地址。简单的看来就是浪费掉256bytes,其实仔细想想这里应该是不需要给usr模式设置栈地址的。
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; Enter User Mode and set its Stack Pointer
; MSR CPSR_c, #Mode_USR
IF [s:154]EF:__MICROLIB
EXPORT __initial_sp
ELSE
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
ENDIF
单这边修改还不够,下面的user_initial_stackheap 段代码也要做对应修改,否则在main里面还会把地址置回去。
__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
ENDIF
题外话
我跟踪到__main
的__user_setup_stackheap
函数发现其中有个奇怪的地方,拿出来讨论一下
这个函数地址在这里,是个库函数
__user_setup_stackheap 0x00103d34 ARM Code 96 sys_stackheap_outer.o(.text)
找不到代码,只好跟踪汇编
__user_setup_stackheap:
0x00103D34 E1A0500E MOV R5,R14
0x00103D38 EB000018 BL 0x00103DA0
0x00103D3C E1A0E005 MOV R14,R5
0x00103D40 E1B05000 MOVS R5,R0
0x00103D44 E1A0100D MOV R1,R13
0x00103D48 E1A0300A MOV R3,R10
0x00103D4C E3C00007 BIC R0,R0,#0x00000007
0x00103D50 E1A0D000 MOV R13,R0
0x00103D54 E28DD060 ADD R13,R13,#0x00000060
0x00103D58 E92D4020 STMDB R13!,{R5,R14}
0x00103D5C EBFFFCE4 BL __user_initial_stackheap(0x001030F4)
0x00103D60 E8BD4020 LDMIA R13!,{R5,R14}
0x00103D64 E3A06000 MOV R6,#global_variable(0x00000000)
0x00103D68 E3A07000 MOV R7,#global_variable(0x00000000)
0x00103D6C E3A08000 MOV R8,#global_variable(0x00000000)
0x00103D70 E3A0B000 MOV R11,#global_variable(0x00000000)
0x00103D74 E3C11007 BIC R1,R1,#0x00000007
0x00103D78 E1A0C005 MOV R12,R5
0x00103D7C E8AC09C0 STMIA R12!,{R6-R8,R11}
0x00103D80 E8AC09C0 STMIA R12!,{R6-R8,R11}
0x00103D84 E8AC09C0 STMIA R12!,{R6-R8,R11}
0x00103D88 E8AC09C0 STMIA R12!,{R6-R8,R11}
0x00103D8C E1A0D001 MOV R13,R1
0x00103D90 E12FFF1E BX R14
exit:
0x00103D94 0004 LSL R4,R0,#0
0x00103D96 46C0 NOP
0x00103D98 46C0 NOP
0x00103D9A 0020 LSL R0,R4,#0
0x00103D9C F7FC BL $Ven$TA$I$$__rt_exit(0x001002CC) - Part #1
0x00103D9E FA96 BL $Ven$TA$I$$__rt_exit(0x001002CC) - Part #2
0x00103DA0 E59F0000 LDR R0,[PC]
0x00103DA4 E12FFF1E BX R14
0x00103DA8 00200534 DD 0x00200534
这里一开始把0x200534
载入R0
,继而载入R13
,然后压栈的两个寄存器,这时候的R13地址不在合法的栈地址内,查map发现在这里
__libspace_start 0x00200534 Data 96 libspace.o(.bss)
我猜想这个过程应该是把这部分数据拿来当个临时堆栈用了一下,因为这时候stack还没设置,不知道是不是这么个意思。
抛个砖先 :)