Where Does the Program Go After It Ends?

Where Does the Program Go After It Ends?

Introduction: For embedded systems, if there is no RTOS running, the main function (main()) in program development needs to keep running indefinitely through some mechanism; it has no endpoint. If you want to exit the main function, what to do specifically is determined by the C language compiler used. Keywords: C51, main, program exit

01 Problem Statement

Today, I saw an interesting question in CSDN’s Single Chip Microcontroller LED Module Definition Function Problem[1]. The questioner was conducting basic C51 programming experiments and wrote a simple C51 program as follows:

#include <REGX51.H>

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

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

The program executed successfully, and it was observed that two LEDs on the experimental board were lit, while the other six were surprisingly dimly lit.

Where Does the Program Go After It Ends?
▲ Figure 1.1 The unlit LEDs on the experimental board are surprisingly dimly lit

If an infinite loop is added in the main program: while(1);, then the “dimly lit” phenomenon on the circuit board will no longer occur.

#include <REGX51.H>

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

void main(void) {
    test(1);
    while(1);
}
Where Does the Program Go After It Ends?
▲ Figure 1.2 The last six LEDs on the experimental board are no longer lit

The difference between the two cases above is that in the second program, the main loop main() function never exits, while in the first program, the main() function exited. It seems that the dimly lit LEDs should be related to what the microcontroller does after the main function exits.

So there remains one question: For ordinary embedded systems, after the main() function exits in C language programming, where does the program go?

02 Where Does the Program Go?

From the code written by the questioner, it seems they are a C51 enthusiast, happily experimenting on a C51 development board with the C51 compiler. They initially did not install the embedded program development convention in the main program void main(void) to keep the program under control in the main function with an infinite loop, leading to the confusing experimental results mentioned earlier.

Note: They are a bold and meticulous person, and their observations are quite careful.

2.1 Pangu Creates the World

In C language programming, all user program worlds start with the main program main(). The task of creating the world for user programs is done by a small piece of Pangu code STARTUP.A51.

Regarding how C51 starts, it has also been tested and explained in the following blog:

  • Execution Flow of 51 Microcontroller Program (STARTUP.A51 Manages Main Function Execution)[2]

Below is an excerpt from the STARTUP.A51 code, which shows that after the microcontroller RESET, Pangu does some preparatory work (initializing global variables, stack pointer) and then jumps directly to: ?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

The above code has also been debugged and verified step by step in the blog Execution Flow of 51 Microcontroller Program (STARTUP.A51)[3].

Where Does the Program Go After It Ends?
▲ Figure 2.1.1 Showing LJMP C_START is entering the main() program

2.2 The End of the World

Since entering the main() function is a long jump, the main function will not normally return to the startup program STARTUP.A51. So where does the program go?

In the blog The While(1) Problem in Microcontroller C Language, the author analyzed the last moments of the main function for both the KEIL compiler and the PIC MAPLAB compiler by disassembling the code.

2.2.1 Keil Compiler

At the end of the main function, the program adds a few lines of code:

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

These statements, the first four, clear the first 128 addresses of our microcontroller’s memory, the fifth defines the stack, and the sixth jumps the program back to the beginning of the main function for execution.

2.2.2 MAPLAB Compiler

In tracking the PIC microcontroller language program, it was found that the last statement of the main() function is reset, which means the microcontroller directly resets. This reset statement is added by the MAPLAB compiler based on the characteristics of the PIC microcontroller.

Conclusion

For embedded systems, if there is no RTOS running, the main function (main()) in program development needs to keep running indefinitely through some mechanism; it has no endpoint.

If you want to exit the main function, what to do specifically is determined by the C language compiler used.

References

[1]

Single Chip Microcontroller LED Module Definition Function Problem: https://ask.csdn.net/questions/7640604?utm_medium=distribute.pc_feed_v2.none-task-ask-ask_personrec_tag-3.pc_personrecdepth_1-utm_source=distribute.pc_feed_v2.none-task-ask-ask_personrec_tag-3.pc_personrec

[2]

Execution Flow of 51 Microcontroller Program (STARTUP.A51 Manages Main Function Execution): https://blog.csdn.net/ChenGuiGan/article/details/88769619

[3]

Execution Flow of 51 Microcontroller Program (STARTUP.A51): https://blog.csdn.net/tangsun999/article/details/45604507

Leave a Comment