搜索
bottom↓
回复: 11

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

[复制链接]
(170465925)

出0入0汤圆

发表于 2015-11-18 22:11:24 | 显示全部楼层 |阅读模式
一、ucosii堆栈
例子:
OS_STK TaskStk[n];

二、数组地址
对于数组,其元素地址是递增的,即:        &TaskStk[0] < &TaskStk[1] < &TaskStk[2] < ... < &TaskStk[n-1]


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


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

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

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
(170430224)

出0入0汤圆

发表于 2015-11-19 08:06:25 | 显示全部楼层
如果堆栈从内存高地址向低地址方向增长, 常量 OS_STK_GROWTH 应设为 1

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

出0入0汤圆

 楼主| 发表于 2015-11-19 08:37:31 | 显示全部楼层
本帖最后由 Thireven 于 2015-11-19 08:38 编辑
leirui001 发表于 2015-11-19 08:06
如果堆栈从内存高地址向低地址方向增长, 常量 OS_STK_GROWTH 应设为 1

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


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

出0入0汤圆

发表于 2015-11-19 09:00:02 | 显示全部楼层
你对栈顶理解有误
(170426493)

出0入0汤圆

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

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

首次使用堆栈指针是指向任务栈的末地址,也就是高地址。举个例子,比如某任务的栈空间是CPU_STK stack[1024],创建
任务后的栈初始化效果就是这样的:
  1. *   说    明:第一次任务切换前,16个寄存器的存储
  2. *                  |-----------------| stack[0]
  3. *                  |     ....        |
  4. *                  |-----------------|
  5. *                  |     ....        |
  6. *                  |-----------------|      
  7. *      低地址      |     ....        |      
  8. *                  |-----------------|      
  9. *         ^        |       R4        |   
  10. *         ^        |-----------------|           
  11. *         ^        |       R5        |         
  12. *         |        |-----------------|           
  13. *         |        |       R6        |         
  14. *         |        |-----------------|           
  15. *         |        |       R7        |           
  16. *         |        |-----------------|            
  17. *         |        |       R8        |               
  18. *         |        |-----------------|               
  19. *         |        |       R9        |
  20. *         |        |-----------------|
  21. *         |        |      R10        |
  22. *         |        |-----------------|
  23. *         |        |      R11        |
  24. *         |        |-----------------|
  25. *         |        |    R0 = p_arg   |  
  26. *         |        |-----------------|
  27. *         |        |       R1        |
  28. *         |        |-----------------|
  29. *         |        |       R2        |
  30. *         |        |-----------------|
  31. *         |        |       R3        |
  32. *         |        |-----------------|
  33. *         |        |       R12       |
  34. *         |        |-----------------|
  35. *         |        |       LR        |
  36. *         |        |-----------------|
  37. *         |        |    PC = task    |
  38. *         |        |-----------------|
  39. *         |        |      xPSR       |
  40. *     高地址       |-----------------|  stack[1024]
复制代码
(170381583)

出0入0汤圆

 楼主| 发表于 2015-11-19 21:37:06 | 显示全部楼层
cht-rtos 发表于 2015-11-19 09:00
你对栈顶理解有误

是第一个进栈的为栈顶?
(170380777)

出0入0汤圆

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

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

出0入0汤圆

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

对                        
(152775046)

出0入0汤圆

发表于 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);
}

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

出0入0汤圆

发表于 2016-6-10 16:19:57 | 显示全部楼层
OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
(26109743)

出0入4汤圆

发表于 2020-6-15 17:07:46 | 显示全部楼层
Eric2013 发表于 2015-11-19 09:08
注意,STM32的栈方式是向下生长的满栈,也就是从高地址即任务栈的末地址开始给变量,寄存器等需要入栈的 ...

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

谢谢!
(26093096)

出0入0汤圆

发表于 2020-6-15 21:45:13 来自手机 | 显示全部楼层
dadian 发表于 2020-6-15 17:07
你好:
我最近在看ucos,也遇到和LZ一样的疑问。
在你的回答中:从高地址即任务栈的末地址开始给变量,寄 ...

栈顶,指向的是栈的起始单元,换个角度,要是依次从栈里弹出元素的话,栈顶元素那个是垫底出栈。
栈指针,根据栈的生长方向,递增或递减。也就可以确定栈顶的位置。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 ( 公安交互式论坛备案:44190002001997 粤ICP备09047143号 )

GMT+8, 2021-4-13 21:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表