搜索
bottom↓
回复: 4

请教关于堆栈的问题~

[复制链接]

出0入0汤圆

发表于 2009-8-24 23:25:18 | 显示全部楼层 |阅读模式
问题1:
《第五篇: 完善的协作式的内核 》里面的寄存器变量OSTaskRunningPrio的运算很不对劲!!!
定义方式:register unsigned char OSTaskRunningPrio asm("r3");//正在运行的任务
语    句:OSRdyTbl &= ~(1<<OSTaskRunningPrio);
编译后的汇编结果:
+00000121:   2DE3        MOV     R30,R3           Copy register
+00000122:   E0F0        LDI     R31,0x00         Load immediate
+00000123:   E081        LDI     R24,0x01         Load immediate
+00000124:   E090        LDI     R25,0x00         Load immediate
+00000125:   C002        RJMP    PC+0x0003        Relative jump
+00000126:   0F88        LSL     R24              Logical Shift Left
+00000127:   1F99        ROL     R25              Rotate Left Through Carry
+00000128:   943A        DEC     R3               Decrement
+00000129:   F7E2        BRPL    PC-0x03          Branch if plus
+0000012A:   9580        COM     R24              One's complement
+0000012B:   2228        AND     R2,R24           Logical AND

“r3”寄存器的值竟然被改的面目全非了!!!后续也没有还原!!!
很恶心的地方!是编译器的问题么?花费了偶2天的时间(汇编菜鸟哈)!


问题2:
原帖地址:http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=574348&bbs_id=3004
里面的任务调度函数压栈的寄存器是不是有点问题啊?
我使用AVR STUDIO 仿真来看中断函数的压栈,如下:
@0000016C: __vector_9
150:      {
+0000016C:   921F        PUSH    R1               Push register on stack
+0000016D:   920F        PUSH    R0               Push register on stack
+0000016E:   B60F        IN      R0,0x3F          In from I/O location
+0000016F:   920F        PUSH    R0               Push register on stack
+00000170:   2411        CLR     R1               Clear Register
+00000171:   932F        PUSH    R18              Push register on stack
+00000172:   933F        PUSH    R19              Push register on stack
+00000173:   934F        PUSH    R20              Push register on stack
+00000174:   935F        PUSH    R21              Push register on stack
+00000175:   936F        PUSH    R22              Push register on stack
+00000176:   937F        PUSH    R23              Push register on stack
+00000177:   938F        PUSH    R24              Push register on stack
+00000178:   939F        PUSH    R25              Push register on stack
+00000179:   93EF        PUSH    R30              Push register on stack
+0000017A:   93FF        PUSH    R31              Push register on stack
+0000017B:   2D42        MOV     R20,R2           Copy register
+0000017C:   E6E2        LDI     R30,0x62         Load immediate
+0000017D:   E0F0        LDI     R31,0x00         Load immediate
+0000017E:   E020        LDI     R18,0x00         Load immediate

但是原帖里面使用的顺序是:
//根据中断时保存寄存器的次序入栈,模拟一次中断后,入栈的情况
        __asm__ __volatile__("PUSH __zero_reg__");//R1
        __asm__ __volatile__("PUSH __tmp_reg__");//R0
       
        //保存状态寄存器SREG
        __asm__ __volatile__("IN __tmp_reg__,__SREG__");//先将SREG转存到temp_reg,再PUSH
        __asm__ __volatile__("PUSh __tmp_reg__");//保存状态寄存器SREG
       
        __asm__ __volatile__("CLR __zero_reg__");//重新清零R0临时寄存器
       
        __asm__ __volatile__("PUSH r18");//R18
        __asm__ __volatile__("PUSH r19");//R19
        __asm__ __volatile__("PUSH r20");//R20
        __asm__ __volatile__("PUSH r21");//R21
        __asm__ __volatile__("PUSH r22");//R22
        __asm__ __volatile__("PUSH r23");//R23
        __asm__ __volatile__("PUSH r24");//R24
        __asm__ __volatile__("PUSH r25");//R25
        __asm__ __volatile__("PUSH r26");//R26
        __asm__ __volatile__("PUSH r27");//R27
       
        __asm__ __volatile__("PUSH r30");//R30
        __asm__ __volatile__("PUSH r31");//R31
        //R28与R29用于建立在堆栈上的指针
        __asm__ __volatile__("PUSH r28");//R28
        __asm__ __volatile__("PUSH r29");//R29
        //入栈完

这里到底应该采用那种方案来压栈和出栈呢?(偶是菜鸟,高手误骂哈~)

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

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

出0入0汤圆

发表于 2009-8-26 08:40:34 | 显示全部楼层
没用过AVR,也不了解他的指令集,根据自己的想法说一下,如果错了不好意思。

第一个问题感觉好像没有必要恢复R3寄存器,R3就是用来存放当前运行任务的优先级的,OSRdyTbl &= ~(1<<OSTaskRunningPrio);  这

条语句也就是把当前任务从任务就绪列表中删除(这条语句应该是放在任务切换之前,更改一下任务就绪列表,这条语句完了应该就可以根据更改后的任务就绪列表进行任务切换了),这样也可以给低优先级的任务运行的机会。


OSTaskRunningPrio应该是存放在和每个任务相关的结构体里面的,或者直接通过对就绪任务表的操作就可以知道。没有必要对他放在堆

栈里。

个人观点,谢谢

aaa1982

出0入0汤圆

 楼主| 发表于 2009-8-26 14:22:29 | 显示全部楼层
LS可能没有整体看过《第五篇: 完善的协作式的内核》的代码了。
OSTaskRunningPrio 被当做一个全局变量来使的。只是是以寄存器的形式来使用。可能这样能够优化代码吧。

后来我又认真分析了:
1. 定义方式:register unsigned char OSTaskRunningPrio asm("r3");//正在运行的任务
    “1<<OSTaskRunningPrio” 语句会改变 OSTaskRunningPrio 的值。

2. 定义方式:unsigned char OSTaskRunningPrio ;//正在运行的任务
    “1<<OSTaskRunningPrio” 语句则不会会改变 OSTaskRunningPrio 的值。

也就是说,普通变量是将值中转到寄存器后,用寄存器来运算,移位不会改变原变量值;
      而寄存器变量的移位操作直接改变该寄存器变量的值。

出0入0汤圆

发表于 2009-8-28 11:09:46 | 显示全部楼层
LS的能把你说的《第五篇: 完善的协作式的内核》传上来么,怎么goole到的都不是。

出0入0汤圆

 楼主| 发表于 2009-8-28 13:51:47 | 显示全部楼层
可是我已经贴了地址了~

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

本版积分规则

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

GMT+8, 2024-5-20 13:25

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

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