打造自己的rtos(2)
来源:互联网 发布:c语言传值和传址 编辑:程序博客网 时间:2024/04/29 20:14
-------------第二篇: 人工堆栈
在单片机的指令集中,一类指令是专门与堆栈和PC指针打道的,它们是
rcall 相对调用子程序指令
icall 间接调用子程序指令
ret 子程序返回指令
reti 中断返回指令
对于ret和reti,它们都可以将堆栈栈顶的两个字节被弹出来送入程序计数器PC中,一般用来从子程序或中断中退出。其中reti还可以在退出中断时,重开全局中断使能。
有了这个基础,就可以建立我们的人工堆栈了。
例:
#include <avr/io.h>
void fun1(void)
{
unsigned char i=0;
while(1)
{
PORTB=i++;
PORTC=0x01<<(i%8);
}
}
unsigned char Stack[100]; //建立一个100字节的人工堆栈
void RunFunInNewStack(void (*pfun)(),unsigned char *pStack)
{
*pStack--=(unsigned int)pfun>>8; //将函数的地址高位压入堆栈,
*pStack--=(unsigned int)pfun; //将函数的地址低位压入堆栈,
SP=pStack; //将堆栈指针指向人工堆栈的栈顶
__asm__ __volatile__("RET /n/t"); //返回并开中断,开始运行fun1()
}
int main(void)
{
RunFunInNewStack(fun1,&Stack[99]);
}
RunFunInNewStack(),将指向函数的指针的值保存到一个unsigned char的数组Stack中,作为人工堆栈。并且将栈顶的数值传递组堆栈指针SP,因此当用"ret"返回时,从SP中恢复到PC中的值,就变为了指向fun1()的地址,开始运行fun1().
上面例子中在RunFunInNewStack()的最后一句嵌入了汇编代码 "ret",实际上是可以去除的。因为在RunFunInNewStack()返回时,编译器已经会加上"ret"。我特意写出来,是为了让大家看到用"ret"作为返回后运行fun1()的过程。
- 打造自己的rtos(2)
- 打造自己的rtos(1)
- 打造自己的rtos(3)
- 打造自己的rtos(4)
- 打造自己的rtos(5)
- 打造自己的rtos(6)
- 打造自己的rtos(7)
- 打造自己的rtos(8)
- 打造自己的rtos(4)
- small rtos自己使用的心得(2)
- 小虎OS(XiaoHuOS)打造自己的RTOS,基于stc12c5a60s2(51内核)的可剥夺多任务管理操作系统
- 国人自己的RTOS——都江堰
- Android:打造一个属于自己的浏览器(2)
- 打造自己的Web(HTTP)服务器
- 打造自己的RMS框架(三)
- 打造自己的CreateObject函数(VB)
- 打造自己的音乐网站(3)
- 打造属于自己的智能家居(一)
- LoadRunner压力测试时监控服务器Linux的资源情况
- (转载)Vim(gvim)编程字体推荐
- 打造自己的rtos(1)
- Java 复习笔记_第2天
- Linux vi命令手册
- 打造自己的rtos(2)
- 大小端、网络字节序问题
- 打造自己的rtos(3)
- 使用Transact-SQL编程
- 一句话木马
- 打造自己的rtos(4)
- vi/vim 命令手册(初级篇)
- 打造自己的rtos(5)
- select的jquery插件