#include <stdio.h>
#include <stdlib.h> //任务槽个数.在本例中并未考虑任务换入换出,所以实际运行的任务有多少个,
//就定义多少个任务槽,不可多定义或少定义
#define MAX_TASKS 5 //任务的栈指针
unsigned char *task_sp[MAX_TASKS]; //最大栈深.最低不得少于2个,保守值为12.
//预估方法:以2为基数,每增加一层函数调用,加2字节.
//如果其间可能发生中断,则还要再加上中断需要的栈深.
//减小栈深的方法:1.尽量少嵌套子程序 2.调子程序前关中断.
#define MAX_TASK_DEP 12 unsigned char task_stack[MAX_TASKS][MAX_TASK_DEP] =
{
0,1,2,3,4,5,6,7,8,9,'a',9,8,7,6,5,4,3,2,1,0,11,12,13,113,31,4
};//任务堆栈. //任务装入函数.将指定的函数(参数1)装入指定(参数2)的任务槽中.
//如果该槽中原来就有任务,则原任务丢失,但系统本身不会发生错误.
//将各任务的函数地址的低字节和高字节分别入在
//task_stack[任务号][0]和task_stack[任务号][1]中
void task_load(unsigned int fn, unsigned char tid)
{
task_sp[tid] = task_stack[tid] + 1;
task_stack[tid][0] = (unsigned int)fn & 0xff;
task_stack[tid][1] = (unsigned int)fn >> 8;
} void func1()
{
static unsigned char i;
i = 0; while(1)
{
if(i<250)
{
i++;
}
if(i>=250)
{
printf("task1\n");
i = 0;
}
//task_switch();
}
}
void func2()
{
static unsigned int j;
j = 0; while(1)
{
if(j<654)
{
j++;
}
if(j>=654)
{
printf("task2\n");
j = 0;
}
//task_switch();
}
} int main()
{
printf("Hello world!\n"); printf("task_stack[0] = %p\n",task_stack[0]);
printf("task_stack+0 = %p\n",task_stack+0);
printf("task_stack+1 = %p\n",task_stack+1);
printf("task_stack+2 = %p\n",task_stack+2);
printf("task_stack+3 = %p\n",task_stack+3);
printf("task_stack+4 = %p\n",task_stack+4); printf("task_stack[0] = %p\n",task_stack[0]);
printf("*(task_stack+0) = %p\n",*(task_stack+0));
printf("*(task_stack+1) = %p\n",*(task_stack+1));
printf("*(task_stack+2) = %p\n",*(task_stack+2));
printf("*(task_stack+3) = %p\n",*(task_stack+3));
printf("*(task_stack+4) = %p\n",*(task_stack+4)); printf("task_stack[0] = %p\n",task_stack[0]);
printf("*(task_stack+0)+0 = %p\n",*(task_stack+0)+0);
printf("*(task_stack+1)+1 = %p\n",*(task_stack+1)+1);
printf("*(task_stack+2)+2 = %p\n",*(task_stack+2)+2);
printf("*(task_stack+3)+3 = %p\n",*(task_stack+3)+3);
printf("*(task_stack+4)+4 = %p\n",*(task_stack+4)+4); task_sp[0] = (task_stack[0]+1);
task_sp[1] = (task_stack[0]+2);
task_sp[2] = (task_stack[0]+3);
task_sp[3] = (task_stack[0]+4);
task_sp[4] = (task_stack[0]+5);
//task_sp[0] = *(task_stack+0)+9;
printf("task_stack = %p\n",task_stack);
printf("task_stack[0] + 5 = %p\n",(task_stack[0] + 5));
printf("task_sp = %p\n",task_sp); printf("\ntask_sp[0] = %d\n",task_sp[0]);
printf("task_sp[1] = %d\n",task_sp[1]);
printf("task_sp[2] = %d\n",task_sp[2]);
printf("task_sp[3] = %d\n",task_sp[3]);
printf("task_sp[4] = %d\n",task_sp[4]); //task_load(func1, 0);//将func1函数装入0号槽
//task_load(func2, 1);//将func2函数装入1号槽
return 0;
}
Hello world!
task_stack[0] = 00403000
task_stack+0 = 00403000
task_stack+1 = 0040300C
task_stack+2 = 00403018
task_stack+3 = 00403024
task_stack+4 = 00403030
task_stack[0] = 00403000
*(task_stack+0) = 00403000
*(task_stack+1) = 0040300C
*(task_stack+2) = 00403018
*(task_stack+3) = 00403024
*(task_stack+4) = 00403030
task_stack[0] = 00403000
*(task_stack+0)+0 = 00403000
*(task_stack+1)+1 = 0040300D
*(task_stack+2)+2 = 0040301A
*(task_stack+3)+3 = 00403027
*(task_stack+4)+4 = 00403034
task_stack = 00403000
task_stack[0] + 5 = 00403005
task_sp = 004050B0 task_sp[0] = 4206593
task_sp[1] = 4206594
task_sp[2] = 4206595
task_sp[3] = 4206596
task_sp[4] = 4206597 Terminated with return code 0
Press any key to continue ...

pc上用C语言模拟51多任务的案例程序的更多相关文章

  1. [数据结构] 用C语言模拟一个简单的队列程序

    #include<stdio.h> #include <stdlib.h> #include<string.h> #include<math.h> // ...

  2. 在PC上测试移动端网站和模拟手机浏览器的5大方法

    在PC上测试移动端网站和模拟手机浏览器的5大方法 来源:互联网 作者:佚名 时间:03-19 10:14:54 [大 中 小]                最近公司要开发网站的移动版,让我准备准备知 ...

  3. PC上安装多个操作系统

    目 录 第1章 绪论    1 1.1 目标    1 1.2 适宜的读者    1 第2章 制作启动U盘    2 2.1 初级安装    2 2.2 启动分析    3 2.3 高级安装    1 ...

  4. mac os x在PC上安装

    系统安装之前的准备工作及安装过程简介 前面我们已经提到,苹果电脑虽然已经采用了x86架构的Intel处理器,但其官方并不提供在非苹果电脑上安装Mac OS的支持.所以,要想在普通PC/笔记本电脑上安装 ...

  5. 让你在PC上调试Web App,UC浏览器发布开发者版

    目前,在手机上使用浏览器访问网页,无法便捷地进行网页语言调试.手机屏幕相对较小且操作不便,直接在手机上进行网页数据调试不太现实. 因此,UC使用技术将手机网页调试信息分离,实现一种能在大屏幕.高配置P ...

  6. 我用爬虫一天时间“偷了”知乎一百万用户,只为证明PHP是世界上最好的语言

    我用爬虫一天时间“偷了”知乎一百万用户,只为证明PHP是世界上最好的语言 2015-08-06 猿圈 我用爬虫一天时间“偷了”知乎一百万用户 只为证明PHP是世界上最好的语言 看了不少朋友圈里推荐的P ...

  7. PC 上的 LVM 灾难修复

    LVM 介绍 LVM 简介 LVM 是逻辑盘卷管理(Logical Volume Manager)的简称,最早是 IBM 为 AIX 研发的存储管理机制.LVM 通过在硬盘和分区之间建立一个逻辑层,可 ...

  8. NFC手机上基于软件的卡模拟 重大利好还是安全噩梦?(转)

    Software Card Emulation in NFC-enabled Mobile Phones: GreatAdvantage or Security Nightmare? Michael ...

  9. 绕过限制,在PC上调试微信手机页面

    场景 假设一个手机页面,开发者对其做了限制,导致只能在微信客户端中打开.而众所周知手机上非常不利于调试页面,所以需要能在电脑上打开并进行调试.这里针对常见的三种页面做一下分析,一一绕过其限制,(当然不 ...

随机推荐

  1. C#基础提升系列——C#文件和流

    C#文件和流 本文主要是对C#中的流进行详细讲解,关于C#中的文件操作,考虑到后期.net core跨平台,相关操作可能会发生很大变化,所以此处不对文件系统(包括目录.文件)过多的讲解,只会描述出在. ...

  2. Codeforces 499C:Crazy Town(计算几何)

    题目链接 给出点A(x1,y1),B(x2,y2),和n条直线(ai,bi,ci,aix + biy + ci = 0),求A到B穿过多少条直线 枚举每条直线判断A.B是否在该直线两侧即可 #incl ...

  3. 随手记--QT

    设置toolButton按钮隐藏(可视化): ui->toolButton->setVisible(true); 改变按钮背景色: ui->toolButton->setSty ...

  4. pgrep,pidof工具的使用

    博客pgrep,pidof工具的使用 最灵活:ps 选项 | 其它命令 按预定义的模式:pgreppgrep [options] pattern-u uid: effective user,生效者-U ...

  5. JDK1.7 hashMap源码分析

    了解HashMap原理之前先了解一下几种数据结构: 1.数组:采用一段连续的内存空间来存储数据.对于指定下标的查找,时间复杂度为O(1),对于给定元素的查找,需要遍历整个数据,时间复杂度为O(n).但 ...

  6. WIN10无法识别安卓设备,提示Windows 无法验证此设备所需的驱动程序的数字签名

    在设备管理器,显示ANDROID设备是感叹号, 不管更新驱动,还是下载什么手机助手自动安装驱动,均不可解. 从属性中查看提示的是“Windows 无法验证此设备所需的驱动程序的数字签名”, 解决办法: ...

  7. lua实现简单

    MessageManager.lua local messageManager = {mEventTable = {},mEventUserData = {}} --注册事件function mess ...

  8. Spring Boot学习一之Spring Beans和依赖注入

    你可以自由地使用任何标准的Spring框架技术去定义beans和它们注入的依赖.简单起见,我们经常使用 @ComponentScan 注解搜索beans,并结合 @Autowired 构造器注入. 如 ...

  9. php面试专题---4、流程控制考点

    php面试专题---4.流程控制考点 一.总结 一句话总结: 理解循环内部机制(指针操作),更易于记忆foreach的reset特性,分支结构中理解了switch...case的执行步骤(跳转表)也就 ...

  10. Qt文件夹遍历

    void FindFile(const QString &_filepath) { QDir dir(_filepath); for each (QFileInfo mfile in dir. ...