Thireven 发表于 2015-11-18 22:11:24

ucosii中堆栈增长方式与栈顶指针的困惑

一、ucosii堆栈
例子:
OS_STK TaskStk;

二、数组地址
对于数组,其元素地址是递增的,即:        &TaskStk < &TaskStk < &TaskStk < ... < &TaskStk


三、增长方式与栈顶栈底
堆栈是“后进先出”模式,第一个进栈的数据,其地址为栈底地址,最后一个进栈的为栈顶,那么关于向上、向下增长方式的栈顶如图:


四、疑问:
按照上面的逻辑:
向上增长模式,栈顶地址为:&TaskStk
向下增长模式,栈顶地址为:&TaskStk

但是
按照《嵌入式实时操作系统μCOS-II原理及应用 任哲编著》这本书中说法:
向上增长模式,栈顶地址为:&TaskStk
向下增长模式,栈顶地址为:&TaskStk

和我分析的是相反的。
请问我有哪一步理解错误了吗?

leirui001 发表于 2015-11-19 08:06:25

如果堆栈从内存高地址向低地址方向增长, 常量 OS_STK_GROWTH 应设为 1

51单片机的堆栈是 向上增长的,不应该设为1。
但是 由于 51 内部的RAM 太小, ucos51 使用外部 xdata 模拟 stack。采用向下方式处理任务栈。
所以, OS_STK_GROWTH   为   1

Thireven 发表于 2015-11-19 08:37:31

本帖最后由 Thireven 于 2015-11-19 08:38 编辑

leirui001 发表于 2015-11-19 08:06
如果堆栈从内存高地址向低地址方向增长, 常量 OS_STK_GROWTH 应设为 1

51单片机的堆栈是 向上增长的,不应 ...

这个我明白,我不明白的地方是我分析出来的栈顶和那本书里面给出来的相反......另外,我的硬件平台是stm32的

cht-rtos 发表于 2015-11-19 09:00:02

你对栈顶理解有误

Eric2013 发表于 2015-11-19 09:08:36

Thireven 发表于 2015-11-19 08:37
这个我明白,我不明白的地方是我分析出来的栈顶和那本书里面给出来的相反......另外,我的硬件平台是stm3 ...

注意,STM32的栈方式是向下生长的满栈,也就是从高地址即任务栈的末地址开始给变量,寄存器等需要入栈的分配栈空间。

首次使用堆栈指针是指向任务栈的末地址,也就是高地址。举个例子,比如某任务的栈空间是CPU_STK stack,创建
任务后的栈初始化效果就是这样的:
*   说    明:第一次任务切换前,16个寄存器的存储
*                  |-----------------| stack
*                  |   ....      |
*                  |-----------------|
*                  |   ....      |
*                  |-----------------|      
*      低地址      |   ....      |      
*                  |-----------------|      
*         ^      |       R4      |   
*         ^      |-----------------|         
*         ^      |       R5      |         
*         |      |-----------------|         
*         |      |       R6      |         
*         |      |-----------------|         
*         |      |       R7      |         
*         |      |-----------------|            
*         |      |       R8      |               
*         |      |-----------------|               
*         |      |       R9      |
*         |      |-----------------|
*         |      |      R10      |
*         |      |-----------------|
*         |      |      R11      |
*         |      |-----------------|
*         |      |    R0 = p_arg   |
*         |      |-----------------|
*         |      |       R1      |
*         |      |-----------------|
*         |      |       R2      |
*         |      |-----------------|
*         |      |       R3      |
*         |      |-----------------|
*         |      |       R12       |
*         |      |-----------------|
*         |      |       LR      |
*         |      |-----------------|
*         |      |    PC = task    |
*         |      |-----------------|
*         |      |      xPSR       |
*   高地址       |-----------------|stack

Thireven 发表于 2015-11-19 21:37:06

cht-rtos 发表于 2015-11-19 09:00
你对栈顶理解有误

是第一个进栈的为栈顶?

Thireven 发表于 2015-11-19 21:50:32

Eric2013 发表于 2015-11-19 09:08
注意,STM32的栈方式是向下生长的满栈,也就是从高地址即任务栈的末地址开始给变量,寄存器等需要入栈的 ...

我懂了,创建任务的时候,任务堆栈还是空的,没有存放数据,这个时候栈顶和栈底是重合的。
所以向下增长模式,应该是向栈中压入数据时,栈顶指针时向下偏移的。也就是“向下增长”指的是栈顶指针是“向下偏移”的意思。
是否这样理解?

Eric2013 发表于 2015-11-19 22:19:10

Thireven 发表于 2015-11-19 21:50
我懂了,创建任务的时候,任务堆栈还是空的,没有存放数据,这个时候栈顶和栈底是重合的。
所以向下增长 ...

对                        

wangyan915205 发表于 2016-6-10 16:19:23

{
    OS_STK *stk;


    (void)opt;                                 /* 'opt' is not used, prevent warning               */
    stk       = ptos;                            /* Load stack pointer                                 */

                                                 /* Registers stacked as if auto-saved on exception    */
    *(stk)    = (INT32U)0x01000000L;             /* xPSR                                             */
    *(--stk)= (INT32U)task;                  /* Entry Point                                        */
    *(--stk)= (INT32U)0xFFFFFFFEL;             /* R14 (LR) (init value will cause fault if ever used)*/
    *(--stk)= (INT32U)0x12121212L;             /* R12                                                */
    *(--stk)= (INT32U)0x03030303L;             /* R3                                                 */
    *(--stk)= (INT32U)0x02020202L;             /* R2                                                 */
    *(--stk)= (INT32U)0x01010101L;             /* R1                                                 */
    *(--stk)= (INT32U)p_arg;                   /* R0 : argument                                    */

                                                 /* Remaining registers saved on process stack         */
    *(--stk)= (INT32U)0x11111111L;             /* R11                                                */
    *(--stk)= (INT32U)0x10101010L;             /* R10                                                */
    *(--stk)= (INT32U)0x09090909L;             /* R9                                                 */
    *(--stk)= (INT32U)0x08080808L;             /* R8                                                 */
    *(--stk)= (INT32U)0x07070707L;             /* R7                                                 */
    *(--stk)= (INT32U)0x06060606L;             /* R6                                                 */
    *(--stk)= (INT32U)0x05050505L;             /* R5                                                 */
    *(--stk)= (INT32U)0x04040404L;             /* R4                                                 */

    return (stk);
}

这个函数中,可以看出地址是递减的;但是不明白右边参数赋值有什么要求?

wangyan915205 发表于 2016-6-10 16:19:57

OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)

dadian 发表于 2020-6-15 17:07:46

Eric2013 发表于 2015-11-19 09:08
注意,STM32的栈方式是向下生长的满栈,也就是从高地址即任务栈的末地址开始给变量,寄存器等需要入栈的 ...

你好:
我最近在看ucos,也遇到和LZ一样的疑问。
在你的回答中:从高地址即任务栈的末地址开始给变量,寄存器等需要入栈的分配栈空间
意思是刚开始分配的时候,栈顶和栈底都指向stack的位置,
随着变量和既存器压栈,栈底始终在stack,而栈顶则stack,stack,.....,stack
是这样吗?

谢谢!

security 发表于 2020-6-15 21:45:13

dadian 发表于 2020-6-15 17:07
你好:
我最近在看ucos,也遇到和LZ一样的疑问。
在你的回答中:从高地址即任务栈的末地址开始给变量,寄 ...

栈顶,指向的是栈的起始单元,换个角度,要是依次从栈里弹出元素的话,栈顶元素那个是垫底出栈。
栈指针,根据栈的生长方向,递增或递减。也就可以确定栈顶的位置。
页: [1]
查看完整版本: ucosii中堆栈增长方式与栈顶指针的困惑