搜索
bottom↓
回复: 6

uCOS/ii堆栈初始化函数OSTaskStkInit(),初始化R0=0x00,R1=0x01,R2=0x02;为什么任务“第

[复制链接]

出0入0汤圆

发表于 2010-11-17 08:40:06 | 显示全部楼层 |阅读模式
uCOS/ii堆栈初始化函数OSTaskStkInit()初始化任务堆栈时,“官网中使用ICC编译器”给出的初始化任务堆栈寄存器的初值如下:
       R0=0x00,
       R1=0x01,
       R2=0x02;
       R3=0x03,
       R4=0x04,
       R5=0x05;


       问题1:该任务用C语言编写,为什么该任务“第一次”被调度时,不会影响任务的执行?

             难道编译器就非常聪明,只使用“已经在用户代码中用户亲自赋过初值的寄存器吗?

       我记得前几年我使用汇编语言编写程序时,
         (1)、编写子程序时,还要考虑子程序中使用的寄存器是否会影响到主函数的寄存器数值

           
         
       问题2:
             如果该任务使用“汇编语言”编写,该任务“第一次”被调度时,会不会影响任务的执行?

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-11-17 09:16:06 | 显示全部楼层
任务第一次调用时,编译器才分配栈给任务相关的参数,变量,所以栈初始化时的值是无关的.

出0入0汤圆

发表于 2010-11-17 09:20:14 | 显示全部楼层
R0=0x00,
       R1=0x01,
       R2=0x02;
       R3=0x03,
       R4=0x04,
       R5=0x05;

上面描述有点问题,
OSTaskStkInit()并没有对R0-R31初始化,而是对任务自已栈顶开始的一些单元初始化.

出0入0汤圆

 楼主| 发表于 2010-11-17 10:57:21 | 显示全部楼层
假定:任务A 为待中止任务,任务B为第一次准备占用CPU的任务。

          当第一次切换到任务B时,做任务切换。

   

       (1)、第一步: 首先将当前CPU的SP保存到“待中止任务A的任务控制块”中,然后将CPU的PSW、PC、R0、R1...R31保存到待中止任务A的堆栈中。

       (2)、第二步:CUP 的SP 指向 “第一次被调用任务B”的任务控制块中保存的堆栈起始地址。
               然后将OSTaskStkInit()中初始化的R0-R31(初值为0x00-0x31)依次弹出到CPU 的R0-R31寄存器中。
        (3)、跳转到任务B执行。



      以上是我的理解。

      OSTaskStkInit()初始化的值时,会将初始值保存到该任务的“私栈”中

      也就是说“第一次被调用的任务B”会把“私栈”中保存的初始值弹到 CPU 的通用寄存器(PSW、PC、R0-R31),既然如此,

       会为什么初始化任务堆栈时,将R0-R31寄存器对应的初始值,初始化为“0x01-0x31”为什么不会影响“任务首次被调度”的执行呢?
      我有点想不明白?

出0入0汤圆

发表于 2010-11-17 11:33:09 | 显示全部楼层
我觉得,任务首次被调度时,R0-R31首次被编译器赋值,主要是存储任务中参数,局部变量等值,R0-R31不够存这些变量时,再存到任务的私栈中。

出0入0汤圆

发表于 2010-11-17 13:18:00 | 显示全部楼层
初次进入任务时,实质是进入一个函数,只不过这个函数没有调用者,而是直接让程序指针指向这个函数

那么可以从函数调用的角度来理解,假定A函数中调用B函数
void A()
{
    B(参数1,...);
}
从A传递给B的参数就是通过寄存器来传递的,当然,编译器在调用B函数之前会将必要的寄存器值压栈。也就是说,对于B函数来说,我只需要知道传递过来的参数就可以了,这些参数是保存在几个寄存器里面的。对于ARM来说,传递参数用寄存器R0-R3.如果只传递一个参数,就只用R0.至于R1开始的寄存器在B函数中被使用时,都会重新赋值。这也就是说R1开始的寄存器在函数被调用时初始值并不重要。

也可以这么理解,如果B函数只有一个参数,那个当A调用B时,只会通过寄存器R0传递参数,而其它寄存器的值,都是A运行到此时的环境,对于B函数来说这些寄存器的值是不确定的,但B不还是可以很好的运行吗?

可以写个简单的只有一个参数的函数,看看编译出来的汇编代码就知道了。

任务初次被调用时,直接赋值程序寄存器PC指针的方法与函数调用的原理差不多,只不过在子函数调用时需要保存寄存器的值,而任务初次调用时,不需要保存。

我上面说的是从ARM的角度,如有错误,请指正。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-19 15:03

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

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