• [转]再识Cortex-M3之堆栈


    原地址https://blog.csdn.net/liaoxu02/article/details/48107651

    Cortex-M3拥有通用寄存器R0-R15以及一些特殊功能寄存器。R0-R12是最”通用目的“的,绝大多数的16位指令只能使用R0-R7,而32位的Thumb-2指令则可以访问所有的通用寄存器。特殊功能寄存器必须通过专用的指令来访问。
    通用目的寄存器R0-R7
    R0-R7称为低组寄存器。所有指令都可以访问,R8-R12称为高组寄存器,只有很少的16位Thumb指令能访问他们,32位的Thumb-2指令则不受限制。

    访问堆栈用堆栈指针,并且PUSH指令和POP指令默认使用SP。
    堆栈的PUSH与POP
    堆栈是一种存储器的使用模型。它由一块连续的内存和一个栈顶指针组成,用于实现”后进先出“的缓冲区。其最典型的应用,就是在数据处理前先保存寄存器的值,再在处理任务完成后从中恢复先前保护的这些值。
    注:寄存器的PUSH和POP操作永远都是4字节对齐的。原因是:堆栈指针的最低两位永远是0。

    栈内存操作
    在Cortex-M3中,除了可以使用PUSH和POP指令来处理堆栈外,内核还会在异常处理的始末自动PUSH和POP操作。
    堆栈的基本操作
    堆栈的功能就是把寄存器的数据临时备份在内存中,以便将来能恢复之——在一个任务或一段子程序执行完毕后恢复。

    .....(主程序)
    ; R0, R1=Y, R2=Z
    BL   Fx1
                      Fx1
                      PUSH {R0}   ;把R0存入栈&调整SP
                      PUSH {R1}   ;把R1存入栈&调整SP
                      PUSH {R2}   ;把R2存入栈&调整SP
                      .....       ;执行Fx1的功能,中途可以改变R0-R2的值
                      POP  {R2}   ;恢复R2早先的值&再次调整SP
                      POP  {R1}   ;恢复R1早先的值&再次调整SP
                      POP  {R0}   ;恢复R0早先的值&再次调整SP
                      BX   LR     ;返回
    ;返回主程序
    ;R0=X,R1=Y.R2=Z(调用Fx1的前后R0-R2的值完好无损)

    PUSH/POP指令足够体贴,支持一次操作多个寄存器。

    Cortex-M3的堆栈实现
    Cortex-M3使用的是”向下生长的满栈“模型。堆栈指针SP指向一个被压入堆栈的32位数值。在下一次压栈时,SP先自减4,在存入新的数值。如下图:

    这里写图片描述

    在看看Cortex-M3的双堆栈机制
    我们上面已经知道了堆栈是分为两个:主堆栈和进程堆栈,CONTROL[1]决定如何选择。
    当CONTROL[1]=0时,只使用MSP,此时用户程序和异常handler共享同一个堆栈。
    这里写图片描述
    当CONTROL=[1]=1时,线程模式将不再使用MSP,而改用PSP(handler模式永远使用MSP)。
    这里写图片描述
    这样的好处是:在使用OS的环境下,只要OS内核仅在handler模式下执行,用户应用程序仅在用户模式下执行,这样就可以防止用户程序的堆栈错误破坏OS使用的堆栈。
    通过读取PSP的值,OS就能够获取用户应用程序使用的堆栈,进一步地知道了在发生异常时,被压入寄存器的内容,而且还可以把其它寄存器进一步压栈。

  • 相关阅读:
    LeetCode做题笔记(4)——error: variable-sized object may not be initialized|
    LeetCode做题笔记(3)——if嵌套if时不加花括号{}导致的bug
    LeetCode做题笔记(2)——使用动态内存分配定义一个二维数组
    数组的初始化
    LeetCode做题笔记(1)——二维数组及qsort的compar函数写法详解
    FreeRTOS 在Tricore上的三种任务切换方式
    FreeRTOS 就绪任务列表与延时任务列表(阻塞态到就绪态的转移原理)
    FreeRTOS vTaskDelay(相对延时)和vTaskDelayUntil(绝对延时)的区别及使用方法
    FreeRTOS 互斥信号量(Mutex)与二值信号量(Binary)的区别
    微信小程序函数间传递url的参数丢失问题
  • 原文地址:https://www.cnblogs.com/libra13179/p/10679942.html
Copyright © 2020-2023  润新知