堆栈操作其实就是对内存的读写,内存地址由堆栈指针SP给出
MSP/PSP
Cortex-M3有两个堆栈指针,它们是banked,任一时刻只能使用其中一个;对堆栈指针SP(R13)的操作是对当前有效的堆栈指针的操作;
两个堆栈分别为:主堆栈MSP和进程堆栈PSP,CONTROL[1]决定选择哪个,当CONTROL[1]=0时,使用MSP,CONTROL=1时,使用PSP;
handler模式永远使用MSP:
- 如果线程模式使用的是MSP,则线程模式和handler使用一个堆栈,即MSP;
- 如果线程模式使用的是PSP,则进入handler时,自动压栈使用的是PSP,进入handler后切换到MSP,退出handler时在切换到PSP;
在特权级下,可以指定具体的堆栈指针进行操作:
MRS R0, MSP
MSR MSP, R0
MRS R0, PSP
MSR PSP, R0
- 1
- 2
- 3
- 4
PUSH/POP指令
Cortex-M3使用的是“向下生长的满栈“模型,堆栈指针指向最后一个被压入堆栈的32位数值;PUSH压栈时,SP先自减4,再存入新值,POP出栈时相反,先从SP指针处读出上次被压入堆栈的值,SP再自增4;
PUSH/POP指令支持一次操作多个寄存器:
PUSH {R0-R2, R8, R12} ;压入R0-R2, R8, R12
POP {R0-R2, R8, R12} ;弹出R0-R2, R8, R12
- 1
- 2
注意:不管在寄存器列表中,寄存器的序号以什么顺序给出,汇编器都将它们升序排列,然后PUSH指令按从大到小的顺序依次入栈,POP指令按从小到大的顺序依次出栈;如果不按升序写寄存器,有些汇编器会给出语法错误;