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

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

3天内不再提示

单片机main函数结束干嘛去了?

jf_pJlTbmA9 来源:TsinghuaJoking 作者:TsinghuaJoking 2023-10-18 17:37 次阅读

正常的程序,都不会跳出main,但是,如果跳出了 main 函数,程序到底去哪儿了,你有相关这个问题吗?

一、问题提出

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

#include 

void test(num) {
    switch(num) {
        case 1: P2_0=0; P2_1=0; 
            break;
    }
}

void main(void) {
    test(1);
}

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

“单片机main函数结束干嘛去了?

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

#include 

void test(num) {
    switch(num) {
        case 1: P2_0=0; P2_1=0; 
            break;
    }
}

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

“单片机main函数结束干嘛去了?

上面两种情况的区别,在于第二个程序中主循环 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_C51STARTUP   SEGMENT   CODE
?STACK          SEGMENT   IDATA

                RSEG    ?STACK
                DS      1

                EXTRN CODE (?C_START)
                PUBLIC  ?C_STARTUP

                CSEG    AT      0
?C_STARTUP:     LJMP    STARTUP1

                RSEG    ?C_C51STARTUP

STARTUP1:

IF IDATALEN <> 0
                MOV     R0,#IDATALEN - 1
                CLR     A
IDATALOOP:      MOV     @R0,A
                DJNZ    R0,IDATALOOP
ENDIF

IF XDATALEN <> 0
                MOV     DPTR,#XDATASTART
                MOV     R7,#LOW (XDATALEN)
  IF (LOW (XDATALEN)) <> 0
                MOV     R6,#(HIGH (XDATALEN)) +1
  ELSE
                MOV     R6,#HIGH (XDATALEN)
  ENDIF
                CLR     A
XDATALOOP:      MOVX    @DPTR,A
                INC     DPTR
                DJNZ    R7,XDATALOOP
                DJNZ    R6,XDATALOOP
ENDIF

IF PPAGEENABLE <> 0
                MOV     PPAGE_SFR,#PPAGE
ENDIF

IF PDATALEN <> 0
                MOV     R0,#LOW (PDATASTART)
                MOV     R7,#LOW (PDATALEN)
                CLR     A
PDATALOOP:      MOVX    @R0,A
                INC     R0
                DJNZ    R7,PDATALOOP
ENDIF

IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)

                MOV     ?C_IBP,#LOW IBPSTACKTOP
ENDIF

IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)

                MOV     ?C_XBP,#HIGH XBPSTACKTOP
                MOV     ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF

IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
                MOV     ?C_PBP,#LOW PBPSTACKTOP
ENDIF

                MOV     SP,#?STACK-1
                LJMP    ?C_START

                END

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

“单片机main函数结束干嘛去了?

2.2 世界尽头

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

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

Keil编译器

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

MOV R0, #0x7F
CLR A
MOV @R0, A
DJNZ R0, (3)
MOV SP, #0x0C
LJMP main

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

MAPLAB编译器

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

总结

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

来源:TsinghuaJoking
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理

审核编辑 黄宇

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

    关注

    237

    文章

    22450

    浏览量

    645894
  • 单片机
    +关注

    关注

    6001

    文章

    43978

    浏览量

    620877
  • 函数
    +关注

    关注

    3

    文章

    3889

    浏览量

    61310
  • main
    +关注

    关注

    0

    文章

    38

    浏览量

    5969
收藏 人收藏

    评论

    相关推荐

    单片机main函数在中断函数里执行?

    最近看了硬汉分享的一个内容:为什么复位中断服务程序里面直接调用的main函数,难道所有程序都在复位中断里面执行的?
    发表于 10-24 11:04 673次阅读

    请问单片机在执行main函数之前要做哪些工作?

    单片机在执行main函数之前都做了哪些工作?是不是还有别的工作先做了?main并不是最先执行的程序?
    发表于 09-05 04:35

    什么叫单片机单片机能干嘛?求解答

    什么叫单片机单片机的标号信息及封装类型又有哪些呢?单片机能干嘛?51单片机都有哪些外部引脚?
    发表于 07-01 08:07

    单片机能干嘛?如何学习单片机

    什么叫单片机单片机的标号信息及封装类型又有哪些呢?单片机能干嘛?如何学习单片机
    发表于 10-21 07:59

    怎么去学习单片机? 学习单片机的目的是干嘛

    怎么去学习单片机?学习单片机的目的是干嘛单片机和linux学习的关系,为什么学习linux?
    发表于 10-25 06:51

    STM32单片机DEBUG不能进入Main函数怎么解决?

    STM32单片机DEBUG不能进入Main函数怎么解决?
    发表于 12-02 06:39

    单片机在执行main函数之前都干了什么

    单片机在执行main函数之前,都干了什么呢?都做了什么准备呢?来总结一下。一 准备用KEIL学STM32单片机编程的时候,按下其仿真按钮再按下RST按钮会发现进入到一个启动文件star
    发表于 12-06 06:18

    STM32单片机程序进入main函数的基础知识汇总

    在刚开始学习单片机的时候,一直以为程序启动后就直接进入到了main函数,但是随着学习的深入才发现,程序在进入main函数前其实还要干好多事情
    发表于 12-06 08:15

    单片机还能有什么秘密呢

    关于单片机中你不知道的秘密单片机还有能有什么秘密呢?基础知识了解上电过程学习总结与深化单片机还有能有什么秘密呢?我们从一开始学C语言或者学习单片机,都从
    发表于 01-20 07:31

    请问51单片机中的看门狗是干嘛的?

    51单片机中的看门狗是干嘛的?
    发表于 10-08 06:06

    STM32系列单片机在进入main函数前都在干些什么?

    在刚开始学习单片机的时候,一直以为程序启动后就直接进入到了main函数,但是随着学习的深入才发现,程序在进入main函数前其实还要干好多事情
    发表于 11-23 18:21 12次下载
    STM32系列<b class='flag-5'>单片机</b>在进入<b class='flag-5'>main</b><b class='flag-5'>函数</b>前都在干些什么?

    单片机 keil调试的时候进入不了main函数

    单片机 keil调试的时候进入不了main函数
    发表于 12-03 20:51 6次下载
    <b class='flag-5'>单片机</b> keil调试的时候进入不了<b class='flag-5'>main</b><b class='flag-5'>函数</b>

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

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

    为什么Python没有main函数

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

    单片机的程序结束后都干嘛去了

    单片机的程序结束后都干嘛去了
    的头像 发表于 10-17 17:16 344次阅读
    <b class='flag-5'>单片机</b>的程序<b class='flag-5'>结束</b>后都<b class='flag-5'>干嘛</b><b class='flag-5'>去了</b>?