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

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

3天内不再提示

C语言编程中main()函数退出之后程序去哪儿了

h1654155149.6853 来源:TsinghuaJoking 作者:TsinghuaJoking 2022-03-22 17:44 次阅读
对于嵌入式系统,如果没有运行RTOS,那么程序开发中的主函数main()需要通过某种机制使其永远愉快的运行下去,它没有终点。如果想从main函数中退出,具体干什么是由所使用的C语言编译器决定的。

一、问题提出

今天在单片机led模块定义函数中看到一个有趣的问题。提问者在进行基本的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()函数退出之后,程序去哪儿了

二、程序去哪儿了?

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

注:他是一个胆大心细的人,观察还挺仔细的。

2.1 盘古开天辟地

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

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)中进行逐步调试跟踪验证过:

a5fdb2e6-964d-11ec-952b-dac502259ad0.png

2.2 世界尽头

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

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

Keil编译器

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

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

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

MAPLAB编译器

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

总结

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

原文标题:干货|单片机的程序结束后都干嘛去了?

文章出处:【微信公众号:电子工程世界】欢迎添加关注!文章转载请注明出处。

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

    关注

    6001

    文章

    43973

    浏览量

    620821
  • 嵌入式系
    +关注

    关注

    0

    文章

    28

    浏览量

    13928
  • C语言
    +关注

    关注

    180

    文章

    7530

    浏览量

    128522

原文标题:干货|单片机的程序结束后都干嘛去了?

文章出处:【微信号:电子工程世界,微信公众号:电子工程世界】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    main函数返回值的认知

    退出,否则代表程序异常退出。在 C89(C语言的早期标准)
    发表于 10-24 11:08

    揭秘嵌入式C语言main函数的写法原因

    但凡是学过C语言的人,都知道要先写main函数,然而很多时候我们看到的main函数却各有差异,这
    发表于 03-05 15:00

    揭秘嵌入式C语言main函数的写法原因

    但凡是学过C语言的人,都知道要先写main函数,然而很多时候我们看到的main函数却各有差异,这
    发表于 03-07 14:43

    每个c语言程序文件中都必须有一个main函数

    每个c语言程序文件中都必须有一个main函数,首页博客学院下载论坛问答活动专题招聘APPVIP会员博客之星写博客5
    发表于 07-20 06:05

    函数编程语言编程程序验证

    函数编程是一种编程范型,它把计算看作是对数学函数的求值,避免了状态和易变数据结构,函数是构造程序
    发表于 04-03 11:01 3次下载

    C语言程序main函数免费下载

    本文档的主要内容详细介绍的是C语言程序main函数免费下载。
    发表于 09-26 14:48 3次下载

    STM8的C语言编程基本程序与启动代码分析

    后开发环境会自动生成 2 个 C 语言程序,一个是 main.c ,另一个是 stm8_interrupt_vector.c 。main.c 中就是一个空的
    发表于 08-18 08:00 3次下载
    STM8的C<b class='flag-5'>语言</b><b class='flag-5'>编程</b>基本<b class='flag-5'>程序</b>与启动代码分析

    C语言main函数有几种写法?

    从学习C语言开始就一直写个一个函数,那么你知道它的标准写法什么什么样吗? main函数,又称主函数,是
    的头像 发表于 10-15 11:04 3067次阅读

    深度剖析C语言main函数

    main的返回值 main函数的返回值用于说明程序退出状态。如果返回0,则代表程序正常
    的头像 发表于 12-18 17:07 4073次阅读

    探究一下C语言main函数各种不同的写法

    main函数是C程序的入口函数,即程序的执行是从main函数
    发表于 08-07 17:26 446次阅读
    探究一下C<b class='flag-5'>语言</b>中<b class='flag-5'>main</b><b class='flag-5'>函数</b>各种不同的写法

    单片机main()函数退出之后程序会跑去哪里?

    对于嵌入式系统,如果没有运行RTOS,那么程序开发中的主函数main()需要通过某种机制使其永远愉快的运行下去,它没有终点。如果想从main函数
    的头像 发表于 03-30 10:01 555次阅读

    C语言编程main函数退出程序哪儿了?

    PIC 单片机语言程序进行跟踪,发现main() 函数最后一条语句为 reset,也就是单片机直接复位,这是 MAPLAB编译器根据 PIC 单片机特点增加的复位语句。
    发表于 05-31 15:28 226次阅读
    C<b class='flag-5'>语言</b><b class='flag-5'>编程</b>中<b class='flag-5'>main</b><b class='flag-5'>函数</b><b class='flag-5'>退出</b>后<b class='flag-5'>程序</b>去<b class='flag-5'>哪儿</b>了?

    main函数不一定就是程序入口

    写个测试代码,代码中有main函数,也有test函数,test就是刚才我们说的入口,不过得指定退出方式,要不然程序运行的时候会出问题。
    的头像 发表于 06-15 17:12 422次阅读

    为什么Python没有main函数

    今天的文章中,我们来讨论一下为什么有的编程语言main函数,而Python为什么没有main函数
    发表于 08-17 11:47 171次阅读

    c语言程序main函数的位置

    C语言程序中的main函数程序的入口点,它被认为是C语言
    的头像 发表于 11-24 10:23 910次阅读