What happened before the main function?

Source: Internet
Author: User

// ================================================ ====================================
// Title:
// What happened before the main function?
// Author:
// Norains
// Date:
// Friday 3-December-2010
// Environment:
// MDK 4.1
// ================================================ ====================================

 

When using MFC, we will think that the entry function is: initinstance; when using Win32 API, we will think that the entry function is winmain; when we write a pure C ++ program, the entry function becomes main again; but when we enter the embedded field, we find that there is still a piece of startup code before the main function!

 

What happened before the main function? If you think you have understood this process, try to answer this question: the program is stored in flash, and the static variable address during runtime is directed to ram, how are the initial values of these static variables mapped to ram?

 

Taking the startup code of stm32f10x as an example, let's take a look at its complete source code:

; /*************************************** ***********************************/< Br/>; /* stm32f10x. s: Startup File for St stm32f10x device series */<br/>; /*************************************** ***********************************/< br/>; /* <use Configuration Wizard in context menu> */<br/>; /*************************************** ***********************************/< br/>; /* this file is part of the uvision/ARM development tools. */<br/>;/* copyright (c) 2005-2007 Keil software. all rights reserved. */<br/>;/* This software may only be used under the terms of a valid, current, */<br/>; /* End User licence from Keil for a compatible version of Keil software */<br/>;/* development tools. nothing else gives you the right to use this software. */<br/>; /*************************************** ***********************************/< /P> <p>; // <p> stack configuration <br/>; // <o> stack size (in bytes) <0x0-0xffffffff: 8> <br/>; // </p> </P> <p> stack_size equ 0x00000200 </P> <p> area stack, noinit, readwrite, align = 3 <br/> stack_mem space stack_size <br/>__ initial_sp </P> <p>; // <p> heap configuration <br/>; // <o> heap size (in bytes) <0x0-0xffffffff: 8> <br/>; // </p> </P> <p> heap_size equ 0x00000000 </P> <p> area heap, noinit, readwrite, align = 3 <br/>__ heap_base <br/> heap_mem space heap_size <br/>__ heap_limit </P> <p> preserve8 <br/> thumb </P> <p>; vector table mapped to address 0 at reset </P> <p> area reset, data, readonly </P> <p> export _ vectors </P> <p >__ vectors DCD _ initial_sp; top of stack <br/> DCD reset_handler; reset handler <br/> DCD nmi_handler; NMI handler <br/> DCD hardfault_handler; hard Fault Handler <br/> DCD memmanage_handler; MPU Fault Handler <br/> DCD busfault_handler; bus Fault Handler <br/> DCD usagefault_handler; usage Fault Handler <br/> DCD 0; reserved <br/> DCD 0; reserved <br/> DCD 0; reserved <br/> DCD 0; reserved <br/> DCD svc_handler; svcall handler <br/> DCD debugmon_handler; debug monitor handler <br/> DCD 0; reserved <br/> DCD pendsv_handler; pendsv handler <br/> DCD javasick_handler; javasick handler </P> <p>; external interrupts <br/> DCD wwdg_irqhandler; window watchdog <br/> DCD pvd_irqhandler; CVD through exti line Detect <br/> DCD tamper_irqhandler; tamper <br/> DCD rtc_irqhandler; RTC <br/> DCD flash_irqhandler; flash <br/> DCD rcc_irqhandler; RCC <br/> DCD exti0_irqhandler; exti line 0 <br/> DCD exti1_irqhandler; exti line 1 <br/> DCD exti2_irqhandler; exti line 2 <br/> DCD exti3_irqhandler; exti line 3 <br/> DCD exti4_irqhandler; exti Line 4 <br/> DCD dmachannel1_irqhandler; DMA Channel 1 <br/> DCD handler; DMA Channel 2 <br/> DCD dmachannel3_irqhandler; DMA Channel 3 <br/> DCD handler; DMA Channel 4 <br/> DCD handler; DMA Channel 5 <br/> DCD dmachannel6_irqhandler; DMA Channel 6 <br/> DCD dmachannel7_irqhandler; DMA Channel 7 <br/> DCD adc_irqhandler; ADC <br/> DCD usb_hp_can_tx_irqhandler; USB high priority or can TX <br/> DCD usb_lp_can_rx0_irqhandler; USB low priority or can rx0 <br/> DCD can_rx1_irqhandler; Can rx1 <br/> DCD can_sce_irqhandler; can SCE <br/> DCD exti9_5_irqhandler; exti line 9 .. 5 <br/> DCD timerebrk_irqhandler; tim1 break <br/> DCD timereup_irqhandler; tim1 update <br/> DCD handler; tim1 trigger and commutation <br/> DCD timerecc_irqhandler; tim1 capture compare <br/> DCD tim2_irqhandler; tim2 <br/> DCD tim3_irqhandler; tim3 <br/> DCD tim4_irqhandler; tim4 <br/> DCD handler; i2c1 event <br/> DCD i2c1_er_irqhandler; i2c1 error <br/> DCD handle; i2c2 event <br/> DCD handle; i2c2 error <br/> DCD spigot irqhandler; spi1 <br/> DCD spi2_irqhandler; spi2 <br/> DCD usart?irqhandler; usart1 <br/> DCD handler; usart2 <br/> DCD handler; usart3 <br/> DCD handler; exti line 15 .. 10 <br/> DCD rtcalarm_irqhandler; RTC Alarm Through exti line <br/> DCD usbwakeup_irqhandler; USB wakeup from suspend </P> <p> area |. text |, code, readonly </P> <p>; reset handler </P> <p> reset_handler proc <br/> export reset_handler [Weak] <br/> Import _ main <br/> LDR r0, ==main <br/> BX R0 <br/> endp </P> <p>; dummy exception handlers (infinite loops which can be modified) </P> <p> nmi_handler proc <br/> export nmi_handler [Weak] <br/> B. <br/> endp <br/> hardfault_handler/<br/> proc <br/> export hardfault_handler [Weak] <br/> B. <br/> endp <br/> memmanage_handler/<br/> proc <br/> export memmanage_handler [Weak] <br/> B. <br/> endp <br/> busfault_handler/<br/> proc <br/> export busfault_handler [Weak] <br/> B. <br/> endp <br/> usagefault_handler/<br/> proc <br/> export usagefault_handler [Weak] <br/> B. <br/> endp <br/> svc_handler proc <br/> export svc_handler [Weak] <br/> B. <br/> endp <br/> debugmon_handler/<br/> proc <br/> export debugmon_handler [Weak] <br/> B. <br/> endp <br/> pendsv_handler proc <br/> export pendsv_handler [Weak] <br/> B. <br/> endp <br/> export ick_handler proc <br/> export ick_handler [Weak] <br/> B. <br/> endp </P> <p> default_handler proc </P> <p> export wwdg_irqhandler [Weak] <br/> export pvd_irqhandler [Weak] <br/> Export tamper_irqhandler [Weak] <br/> export rtc_irqhandler [Weak] <br/> export flash_irqhandler [Weak] <br/> export access [Weak] <br/> export access [Weak] <br/> export exti1_irqhandler [Weak] <br/> export exti2_irqhandler [Weak] <br/> export secret [Weak] <br/> export exti4_irqhandler [Weak] <br/> export dmachanneltransferirqhandler [Weak] <br/> export dmachannel2_irqhandler [Weak] <br/> export access [Weak] <br/> export access [Weak] <br/> export access [weak] <br/> export handler [Weak] <br/> export dmachannel7_irqhandler [Weak] <br/> export adc_irqhandler [Weak] <br/> export handler [Weak] <br/> export handle [Weak] <br/> export can_rx1_irqhandler [Weak] <br/> export can_sce_irqhandler [Weak] <br/> export handle [Weak] <br/> export timelist brk_irqhandler [weak] <br/> export timereup_irqhandler [Weak] <br/> export timeout [Weak] <br/> export timerecc_irqhandler [Weak] <br/> export tim2_irqhandler [Weak] <br /> export tim3_irqhandler [Weak] <br/> export tim4_irqhandler [Weak] <br/> export i2c1_ev_irqhandler [Weak] <br/> export limit [Weak] <br/> [Weak] <br/> export secret [Weak] <br/> export spigot irqhandler [Weak] <br/> export spi2_irqhandler [Weak] <br/> export usart#irqhandler [Weak] <br/> export usart2_irqhandler [Weak] <br/> export usart3_irqhandler [Weak] <br/> export secret [Weak] <br/> export rtcalarm_irqhandler [Weak] <br/> handler [Weak] </P> <p> wwdg_irqhandler <br/> pvd_irqhandler <br/> tamper_irqhandler <br/> rtc_irqhandler <br/> flash_irqhandler <br/> handler <br/> handler <br/> exti1_irqhandler <br/> exti2_irqhandler <br/> exti3_irqhandler <br/> exti4_irqhandler <br/> handler <br/>/> handler <br/> dmachannel5_irqhandler <br/> handler <br/> adc_irqhandler <br/> handler <br/> can_rxw.irqhandler <br/>/> handler <br/> timerebrk_irqhandler <br/> handler <br/> timerecc_irqhandler <br/> tim2_irqhandler <br/> tim3_irqhandler <br/>/> tim4_irqhandler <br/> handler <br/> spi1_irqhandler <br/> spi2_irqhandler <br/> usart#irqhandler <br/> usart2_irqhandler <br/> usart3_irqhandler <br/> exti15_10_irqhandler <br/> rtcalarm_irqhandler <br/> usbwakeup_irqhandler </P> <p> B. </P> <p> endp </P> <p> align </P> <p>; user initial stack & heap </P> <p> If: Def: __microlib </P> <p> export _ initial_sp <br/> export _ heap_base <br/> export _ heap_limit </P> <p> else </P> <p>; import _ use_two_region_memory <br/> export _ user_initial_stackheap <br/>__ user_initial_stackheap </P> <p> LDR r0, = heap_mem <br/> LDR R1, = (stack_mem + stack_size) <br/> LDR R2, = (heap_mem + heap_size) <br/> LDR R3, = stack_mem <br/> bx lr </P> <p> align </P> <p> endif </P> <p> end </P> <p>

Some sub-topics have nothing to do with the topic of this Article. We just need to know that the startup code is to set the vector table and then jump to the _ main function. Jump to the specific part of the code segment as follows:
Reset_handler proc <br/> export reset_handler [Weak] <br/> Import _ main <br/> LDR r0, ==main <br/> BX R0 <br/> endp

 

When we see the _ main function, it is estimated that many people think it is the alias of the main function or the name after compilation, otherwise, the main-Related Words cannot be found in the startup code. The fact is that, __main and main are totally different functions! If this is not enough to surprise you, tell you another fact: you cannot find the _ main code because it is automatically created by the compiler!

 

If you are still skeptical about this, you can view the MDK documentation, you will find such a statement: it is automatically created by the linker when it sees a definition of main (). Simply put, when the compiler finds that the main function is defined, _ main is automatically created.

 

_ The origin of the main function is basically clear, so the question now is, what is the relationship between it and main? In fact, _ main is mainly used to initialize the resources required by C/C ++ and call the main function. I will not talk about initialization for the moment, but the "calling main function" function can solve the problem that the previous startup code calls _ main, but can finally go to the main function.

 

The resources required to initialize C/C ++ are hard to explain if they are different from the actual situation. Let's take a look at the compiled assembly code snippet:
 

 

All operations starting with _ rt are used to initialize the C/C ++ Runtime Library. Operations starting with _ scatterload are defined based on discrete files, map the variables in the Code to the corresponding memory location. The key to answering the question at the beginning of this article is the _ scatterload_copy function!

 

We will give a simple example on the stm32f10x platform. First of all, we need to understand that the flash Address of the platform starts with 0x08000000, which is mainly used to store code, while the SRAM starts with 0x20000000, that is, memory. Then C/C ++ has the following line of code:Static int g_ival = 12;

 

When our program started running, we found through ide that g_ival was mapped to the memory address 0x20000000, and the value was a random number 0xffffbe00, instead of the 12 set in the code,


 

Let's continue executing the program. After the execution is completed _ scatterload_copy, we find that g_ival has become the initial value we need:


 

The next step is the initialization of the C/C ++ library, and finally enters the main function. At this time, everything is ready.

 

If you are confined to the Development of desktop applications, the compiled program has many operating system features, which will bring us great confusion in understanding the running of the program, only when we step into the embedded field and run naked on the CPU without the support of the operating system can we better understand how the software runs. We can only know more clearly at this time, the original main function is not the starting point.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.