请教关于堆栈的问题~
问题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
//入栈完
这里到底应该采用那种方案来压栈和出栈呢?(偶是菜鸟,高手误骂哈~) 没用过AVR,也不了解他的指令集,根据自己的想法说一下,如果错了不好意思。
第一个问题感觉好像没有必要恢复R3寄存器,R3就是用来存放当前运行任务的优先级的,OSRdyTbl &= ~(1<<OSTaskRunningPrio);这
条语句也就是把当前任务从任务就绪列表中删除(这条语句应该是放在任务切换之前,更改一下任务就绪列表,这条语句完了应该就可以根据更改后的任务就绪列表进行任务切换了),这样也可以给低优先级的任务运行的机会。
OSTaskRunningPrio应该是存放在和每个任务相关的结构体里面的,或者直接通过对就绪任务表的操作就可以知道。没有必要对他放在堆
栈里。
个人观点,谢谢
aaa1982 LS可能没有整体看过《第五篇: 完善的协作式的内核》的代码了。
OSTaskRunningPrio 被当做一个全局变量来使的。只是是以寄存器的形式来使用。可能这样能够优化代码吧。
后来我又认真分析了:
1. 定义方式:register unsigned char OSTaskRunningPrio asm("r3");//正在运行的任务
“1<<OSTaskRunningPrio” 语句会改变 OSTaskRunningPrio 的值。
2. 定义方式:unsigned char OSTaskRunningPrio ;//正在运行的任务
“1<<OSTaskRunningPrio” 语句则不会会改变 OSTaskRunningPrio 的值。
也就是说,普通变量是将值中转到寄存器后,用寄存器来运算,移位不会改变原变量值;
而寄存器变量的移位操作直接改变该寄存器变量的值。 LS的能把你说的《第五篇: 完善的协作式的内核》传上来么,怎么goole到的都不是。 可是我已经贴了地址了~
问题2:
原帖地址:http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=574348&bbs_id=3004
页:
[1]