0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

编写一个简单的C51程序

Q4MP_gh_c472c21 来源:TsinghuaJoking 作者:TsinghuaJoking 2022-03-12 11:17 次阅读

简 介: 对于嵌入式系统,如果没有运行RTOS,那么程序开发中的 主函数(main())需要通过某种机制使其永远愉快的运行下去,它没有终点。如果想从main函数中退出,具体干什么是由所使用的C语言编译器决定的。

01 问题提出

今天在CSDN的 单片机led模块定义函数的问题[1] 中看到一个有趣的问题。提问者在进行基本的C51编程实验,编写了一个简单的C51程序如下:

#include

voidtest(num){
switch(num){
case1:P2_0=0;P2_1=0;
break;
}
}

voidmain(void){
test(1);
}

  程序执行完之后,可以看到实验板上的有两个LED被点亮,另外六个居然微微发亮。

  如果在主程序中,增加一个无限循环:while(1); ,则电路板上的就不再会出现“微微点亮”的现象了。

#include

voidtest(num){
switch(num){
case1:P2_0=0;P2_1=0;
break;
}
}

voidmain(void){
test(1);
while(1);
}

  上面两种情况的区别,在于第二个程序中 主循环 main() 函数始终没有退出,而第一个程序,main() 函数退出了。似乎前面LED 微微点亮 应该与 主函数 退出之后,单片机都干了些啥有关系。

那么就剩下一个问题:对于普通的嵌入式系统,C语言编程中 main()函数退出之后,程序去哪儿了?

02 程序去哪儿了?

从上面提问者书写的代码来看,应该是一位C51的爱好者,使用的是C51的编译器,在一款C51开发板上愉快的进行实验。他一开始没有安装嵌入式程序开发的惯例在主程序void main(void) 中利用无限循环将程序控制在主程序函数中,就出现了前面实验结果中令人迷惑的情况。
注:他是一个胆大心细的人,观察还挺仔细的。

2.1 盘古开天辟地

  对于C语言编程来说,所有的用户程序世界是从主程序 main() 开始的。给用户程序开天辟地的任务是由 一小段 盘古代码 STARTUP.A51

  关于C51是如何启动的, 在如下面博文中也被测试说明:

  • 51单片机程序执行流程(STARTUP.A51管理Main函数的执行)

  下面截取了 STARTUP.A51 代码的一段,可以看到盘古在单片机 RESET 之后做了点准备工作(初始化全局变量、堆栈指针)之后,就直接跳转至:?C_START

NAME?C_STARTUP

?C_C51STARTUPSEGMENTCODE
?STACKSEGMENTIDATA

RSEG?STACK
DS1

EXTRNCODE(?C_START)
PUBLIC?C_STARTUP

CSEGAT0
?C_STARTUP:LJMPSTARTUP1

RSEG?C_C51STARTUP

STARTUP1:

IFIDATALEN<>0
MOVR0,#IDATALEN-1
CLRA
IDATALOOP:MOV@R0,A
DJNZR0,IDATALOOP
ENDIF

IFXDATALEN<>0
MOVDPTR,#XDATASTART
MOVR7,#LOW(XDATALEN)
IF(LOW(XDATALEN))<>0
MOVR6,#(HIGH(XDATALEN))+1
ELSE
MOVR6,#HIGH(XDATALEN)
ENDIF
CLRA
XDATALOOP:MOVX@DPTR,A
INCDPTR
DJNZR7,XDATALOOP
DJNZR6,XDATALOOP
ENDIF

IFPPAGEENABLE<>0
MOVPPAGE_SFR,#PPAGE
ENDIF

IFPDATALEN<>0
MOVR0,#LOW(PDATASTART)
MOVR7,#LOW(PDATALEN)
CLRA
PDATALOOP:MOVX@R0,A
INCR0
DJNZR7,PDATALOOP
ENDIF

IFIBPSTACK<>0
EXTRNDATA(?C_IBP)

MOV?C_IBP,#LOWIBPSTACKTOP
ENDIF

IFXBPSTACK<>0
EXTRNDATA(?C_XBP)

MOV?C_XBP,#HIGHXBPSTACKTOP
MOV?C_XBP+1,#LOWXBPSTACKTOP
ENDIF

IFPBPSTACK<>0
EXTRNDATA(?C_PBP)
MOV?C_PBP,#LOWPBPSTACKTOP
ENDIF

MOVSP,#?STACK-1
LJMP?C_START

END

  上面的代码也被博文 51单片机程序执行流程(STARTUP.A51)中进行逐步调试跟踪验证过:

915c6e02-92f3-11ec-952b-dac502259ad0.jpg


▲ 图2.1.1 显示LJMP C_START 就是进入 main() 程序

2.2 世界尽头

  由于进入main() 函数是长跳转,所以main函数是不会正常返回到启动程序 STARTUP.A51,那么程序去哪了?

  在博文 单片机C语言while(1)的问题 中作者对于 KEIL编译器和PIC的 MAPLAB编译器对于main函数的最后时光进行了反汇编查看。

2.2.1 Keil编译器

  在main函数的最后,程序增加了一下几行代码:

MOVR0,#0x7F
CLRA
MOV@R0,A
DJNZR0,(3)
MOVSP,#0x0C
LJMPmain

  这几条语句,前4条,是将我们单片机的内存的前128个地址清零,第5条,是定义堆栈,第6条,是将程序重新跳转到main函数的首行进行执行。

2.2.2 MAPLAB编译器

  PIC 单片机语言程序进行跟踪,发现main() 函数最后一条语句为 reset,也就是单片机直接复位,这是 MAPLAB编译器根据 PIC 单片机特点增加的复位语句。

总  结

对于嵌入式系统,如果没有运行RTOS,那么程序开发中的 主函数(main())需要通过某种机制使其永远愉快的运行下去,它没有终点。

如果想从main函数中退出,具体干什么是由所使用的C语言编译器决定的。

原文标题:程序结束后去哪儿了?

文章出处:【微信公众号:嵌入式ARM】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6030

    文章

    44501

    浏览量

    632281
  • C语言
    +关注

    关注

    180

    文章

    7596

    浏览量

    135961
  • 函数
    +关注

    关注

    3

    文章

    4290

    浏览量

    62346

原文标题:程序结束后去哪儿了?

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C51基本结构程序设计

    C51基本结构程序设计1. 掌握if语句来实现选择结构,能利用if语句编写相应的分枝结构的程序。在嵌套if语句中,定要搞清楚else与哪个
    发表于 06-12 23:44 32次下载

    C51程序的函数教程

    函数是C51程序的基本组成部分,C51程序的全部工作都是由各式各样的函数完成的。本章主要介绍函数的定义、调用、参数的传递、变量的作用域等。1.理解函数的概念,能根据需
    发表于 06-12 23:46 54次下载

    单片机C51编程规范

    单片机C51编程规范 1单片机C51编程规范- 前言   为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范。
    发表于 01-14 21:03 2553次阅读

    Keil C51库函数参考

    第五章 Keil C51库函数参考 C51强大功能及其高效率的重要体现之在于其丰富的可直接调用的库函数,多使用库函数使程序代码简单,结构清
    发表于 04-07 09:45 413次下载

    C51精确延时函数的编写及调试方法

    本内容详细介绍了C51精确延时函数的编写及调试方法
    发表于 05-24 11:33 272次下载
    <b class='flag-5'>C51</b>精确延时函数的<b class='flag-5'>编写</b>及调试方法

    C51语言程序设计技巧

    1 C51语言程序设计\技巧 C语言 是种高级程序设计语言,它提供了十分完备的规范化流程控制结构。因此采用
    发表于 05-17 14:02 5974次阅读
    <b class='flag-5'>C51</b>语言<b class='flag-5'>程序</b>设计技巧

    流水灯的C51程序

    流水灯的C51程序流水灯的C51程序流水灯的C51程序
    发表于 01-07 16:55 3次下载

    C51单片机对液晶片的驱动

    Keil C51编写的192*64液晶片驱动程序,感谢很多网友提供了参考源程序, 本程序是在网友们提供的
    发表于 11-19 16:22 1826次阅读

    如何使用KEIL C51和proteus实现C51汇编程序的设计实例

    本文档的主要内容详细介绍的是如何使用KEIL C51和proteus实现C51汇编程序的设计实例。
    发表于 07-30 17:35 19次下载
    如何使用KEIL <b class='flag-5'>C51</b>和proteus实现<b class='flag-5'>C51</b>汇编<b class='flag-5'>程序</b>的设计实例

    X25045的C51读写程序

    本文档的主要内容详细介绍的是X25045的C51读写程序
    的头像 发表于 01-18 11:13 3084次阅读

    单片机C51语言程序设计基础的资料合集免费下载

    本文档的主要内容详细介绍的是单片机C51语言程序设计基础的资料合集免费下载包括了:单片机开发概述,构建C51集成开发环境,单片机C51语言程序
    发表于 03-16 08:00 18次下载
    单片机<b class='flag-5'>C51</b>语言<b class='flag-5'>程序</b>设计基础的资料合集免费下载

    51单片机读写AT29C040的C51程序

    本文档的主要内容详细介绍的是给大家介绍51单片机读写AT29C040的c51程序
    的头像 发表于 11-07 12:01 4881次阅读

    单片机C51程序设计的学习课件免费下载

    本文档的主要内容详细介绍的是单片机C51程序设计的学习课件免费下载包括了:1、C51程序设计基础,2、C51的数据类型及其在
    发表于 11-24 17:24 63次下载
    单片机<b class='flag-5'>C51</b><b class='flag-5'>程序</b>设计的学习课件免费下载

    Keil C51与单片机开发入门(第一个程序

    Keil C51与单片机开发入门(第一个程序
    发表于 11-13 15:21 11次下载
    Keil <b class='flag-5'>C51</b>与单片机开发入门(第<b class='flag-5'>一个</b><b class='flag-5'>程序</b>)

    c51流水灯程序下载

    c51流水灯程序免费下载。
    发表于 05-20 17:15 10次下载