KEIL uVison: Tutorial3 : Startup flow for a C program.
-Aviral Mittal avimit att yhaoo dat camm.
Connect @

The First Tutorial had a very small startup.s file and a very small C program.
When compiled, it produced tons of compiled code. It was then re-compiled after changing compile options to remove 'debug-info' form the code. Yet the compiled binary code was quite large and did a lot of things, the user apparently did not code.
If the user wants to get rid of all the extra code just to see what their code compiles, then they must write all of the code in assembly language only.
However if the user must write a 'C' program, the compiler/linker will perform a lot of 'behind-the-scenes' steps, usually to help the user. For example memory management. That is to say that the compiler will take care where to place the local variables, where to place the global variables, where to place the loop variables, and make sure that the memory spaces do not overlap, or the memory does not gets corrupted. The compiler does give the user options to have some control over where to place things, but if the user isn't expert, its always best to stick to what compiler does, and not try to change things.
This tutorial is more theoretical in nature, as it explains the startup flow in brief, i.e. what the extra code is all about, and what the compiler does when a c-program is compiled. The full details of the startup flow is beyond the scope of this tutorial.

Default Sequence:
The default sequence looks something like this:

1. Calls __main
This is the entry point of the user's program. This __main function is pre-defined (though the user can write their own __main). Note that this __main is different from the main() in the user's C-program. If the user intends to write their own '__main' they can use their own name for it. However, then the user must update the Linker's default for '--startup' option as it defaults to '--startup=__main'. The user can also use '--no_startup' if they so wish. However the consequences of doing so is beyond the scope of this tutorial.
The purpose of this function is to do some code relocation. It copies the non-root execution region code from their load addresses to their execution addresses. More about regions, root, non-root code, and load/execution regions is described here:
This function also initializes certain region by zeros. For example the startup.s code defines a 'stack' region. This stack region is zero initialized.

2. Calls __rt_entry
It sets up the stack and heap.
Calls __rt_lib_init which in turn initializes library functions.

3. Calls main().
This is when the user's code inside main() is executed.

4. Calls exit().

 <= PREV                                                           NEXT => (no next)