我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 783|回复: 14

[产品新知] C语言编程中main()函数退出之后程序去哪儿了

[复制链接]
  • TA的每日心情

    2024-10-6 20:55
  • 签到天数: 1 天

    [LV.1]初来乍到

    479

    主题

    247

    回帖

    1392

    积分

    二级逆天

    积分
    1392

    终身成就奖特殊贡献奖

    发表于 2022-3-23 09:16:18 | 显示全部楼层 |阅读模式

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

    您需要 登录 才可以下载或查看,没有账号?立即注册

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


    一、问题提出


    今天在单片机led模块定义函数中看到一个有趣的问题。提问者在进行基本的C51编程实验,编写了一个简单的C51程序如下:
    #include<regx51.h>voidtest(num){switch(num){case12_0=02_1=0;break;}}voidmain(void){test(1);}程序执行完之后,可以看到实验板上的有两个LED被点亮,另外六个居然微微发亮。

    如果在主程序中,增加一个无限循环:while(1); ,则电路板上的就不再会出现“微微点亮”的现象了。
    #include<regx51.h>voidtest(num){switch(num){case12_0=02_1=0;break;}}voidmain(void){test(1);while(1);}上面两种情况的区别,在于第二个程序中主循环 main()函数始终没有退出,而第一个程序,main()函数退出了。似乎前面LED微微点亮 应该与主函数退出之后,单片机都干了些啥有关系。
    那么就剩下一个问题:对于普通的嵌入式系统,C语言编程中main()函数退出之后,程序去哪儿了


    二、程序去哪儿了?


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

    2.1 盘古开天辟地

    对于C语言编程来说,所有的用户程序世界是从主程序main()开始的。给用户程序开天辟地的任务是由一小段盘古代码STARTUP.A51。
    51单片机程序执行流程(STARTUP.A51管理Main函数的执行)
    下面截取了STARTUP.A51 代码的一段,可以看到盘古在单片机RESET之后做了点准备工作(初始化全局变量、堆栈指针)之后,就直接跳转至:?C_START
    NAME?C_STARTUP?C_C51STARTUPSEGMENTCODE?STACKSEGMENTIDATARSEG?STACKDS1EXTRNCODE(?C_START)PUBLIC?C_STARTUPCSEGAT0?C_STARTUPJMPSTARTUP1RSEG?C_C51STARTUPSTARTUP1:IFIDATALEN<>0MOVR0,#IDATALEN-1CLRAIDATALOOP:MOV@R0,ADJNZR0,IDATALOOPENDIFIFXDATALEN<>0MOVDPTR,#XDATASTARTMOVR7,#LOW(XDATALEN)IF(LOW(XDATALEN))<>0MOVR6,#(HIGH(XDATALEN))+1ELSEMOVR6,#HIGH(XDATALEN)ENDIFCLRAXDATALOOP:MOVX@DPTR,AINCDPTRDJNZR7,XDATALOOPDJNZR6,XDATALOOPENDIFIFPPAGEENABLE<>0MOVPPAGE_SFR,#PPAGEENDIFIFPDATALEN<>0MOVR0,#LOW(PDATASTART)MOVR7,#LOW(PDATALEN)CLRAPDATALOOP:MOVX@R0,AINCR0DJNZR7,PDATALOOPENDIFIFIBPSTACK<>0EXTRNDATA(?C_IBP)MOV?C_IBP,#LOWIBPSTACKTOPENDIFIFXBPSTACK<>0EXTRNDATA(?C_XBP)MOV?C_XBP,#HIGHXBPSTACKTOPMOV?C_XBP+1,#LOWXBPSTACKTOPENDIFIFPBPSTACK<>0EXTRNDATA(?C_PBP)MOV?C_PBP,#LOWPBPSTACKTOPENDIFMOVSP,#?STACK-1LJMP?C_STARTEND上面的代码也被博文51单片机程序执行流程(STARTUP.A51)中进行逐步调试跟踪验证过:

                                   
    登录/注册后可看大图


    2.2 世界尽头

    由于进入main()函数是长跳转,所以main函数是不会正常返回到启动程序STARTUP.A51,那么程序去哪了?
    在博文单片机C语言while(1)的问题中作者对于KEIL编译器和PIC的MAPLAB编译器对于main函数的最后时光进行了反汇编查看。
    Keil编译器
    在main函数的最后,程序增加了一下几行代码:
    MOVR0,#0x7FCLRAMOV@R0,ADJNZR0,(3)MOVSP,#0x0CLJMPmain这几条语句,前4条,是将我们单片机的内存的前128个地址清零,第5条,是定义堆栈,第6条,是将程序重新跳转到main函数的首行进行执行。
    MAPLAB编译器
    PIC 单片机语言程序进行跟踪,发现main() 函数最后一条语句为 reset,也就是单片机直接复位,这是 MAPLAB编译器根据 PIC 单片机特点增加的复位语句。


    总结


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

    使用道具 举报

    该用户从未签到

    1

    主题

    300

    回帖

    0

    积分

    PADS20220105初级班

    积分
    0

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2022-3-23 09:19:01 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    146

    回帖

    58

    积分

    一级逆天

    积分
    58

    终身成就奖

    发表于 2022-3-23 09:34:41 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    3 天前
  • 签到天数: 86 天

    [LV.6]常住居民II

    51

    主题

    3999

    回帖

    3146

    积分

    二级逆天

    积分
    3146

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    QQ
    发表于 2022-3-23 11:09:28 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    昨天 21:40
  • 签到天数: 136 天

    [LV.7]常住居民III

    27

    主题

    3466

    回帖

    4455

    积分

    1元学习Allegro(1期)

    积分
    4455

    终身成就奖幽默大师奖灌水天才奖特殊贡献奖原创先锋奖优秀斑竹奖

    发表于 2022-3-23 11:25:43 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    4

    主题

    1318

    回帖

    1225

    积分

    二级逆天

    积分
    1225

    终身成就奖

    发表于 2022-3-24 08:56:26 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    前天 08:32
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    31

    主题

    1696

    回帖

    1487

    积分

    二级逆天

    积分
    1487

    社区居民终身成就奖

    QQ
    发表于 2022-3-25 08:31:34 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    昨天 08:49
  • 签到天数: 159 天

    [LV.7]常住居民III

    3

    主题

    7147

    回帖

    1万

    积分

    PADS20220105初级班

    积分
    10866

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    发表于 2022-3-25 09:01:41 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    515

    回帖

    0

    积分

    二级逆天

    积分
    0

    终身成就奖

    QQ
    发表于 2022-3-25 09:12:55 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    6218

    回帖

    8731

    积分

    二级逆天

    积分
    8731

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    QQ
    发表于 2022-3-25 09:20:12 | 显示全部楼层
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    每日签到,有金币领取。


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    ( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

    平平安安
    TOP
    快速回复 返回顶部 返回列表