Startup code — vector table, reset handler, stack initialization
WHY does startup code even exist?
WHAT happens physically at reset (ARM Cortex-M example):
- CPU reads the first word of memory → loads it into the Main Stack Pointer (MSP).
- CPU reads the second word → loads it into the Program Counter (PC) — this is the address of the Reset Handler.
- Execution begins at the Reset Handler.
The Vector Table
Offset Contents
0x00 Initial MSP value (top of stack)
0x04 Reset_Handler (entry point)
0x08 NMI_Handler
0x0C HardFault_Handler
... ...
0x40+ IRQ0, IRQ1, ... (peripheral interrupts)
In C, the table is just a const array of function pointers placed in a special linker section:
__attribute__((section(".isr_vector")))
void (* const vector_table[])(void) = {
(void (*)(void)) &_estack, // 0x00: top of stack (NOT a function!)
Reset_Handler, // 0x04
NMI_Handler, // 0x08
HardFault_Handler, // 0x0C
/* ... */
};The Reset Handler — manufacturing the C environment
The Reset Handler runs before main(). Its job is to make these C facts true:
| C source | Needs at runtime |
|---|---|
int g = 42; (initialized global) |
The value 42 must be copied from Flash into the variable's RAM address |
int z; (uninitialized global) |
Must be zeroed |
main() calls functions |
Stack must work |
extern uint32_t _sidata, _sdata, _edata, _sbss, _ebss, _estack;
void Reset_Handler(void) {
uint32_t *src = &_sidata;
uint32_t *dst = &_sdata;
while (dst < &_edata) *dst++ = *src++; // copy .data
for (dst = &_sbss; dst < &_ebss; ) *dst++ = 0; // zero .bss
__libc_init_array(); // C++/static constructors
main();
while (1) { } // trap: main must never return
}Stack Initialization
So _estack is set by the linker to the highest RAM address + 1 (the end). Loaded into MSP at reset, the first push lands just below it.

Flashcards
What three things does startup code provide to enable a C program on bare metal?
.data (copied Flash→RAM) and zeroed .bss, and an entry vector to main.On Cortex-M, what does the hardware load from the first two words of the vector table at reset?
Why is vector table entry 0 NOT a real function pointer?
What is the difference between .data and .bss?
.data = initialized globals (values stored in Flash, copied to RAM at reset). .bss = zero-initialized globals (no Flash storage; cleared to 0 at reset).What linker symbols drive the .data copy and why?
_sidata (Flash source), _sdata/_edata (RAM dest range). Copy maps each RAM offset to the same Flash offset from _sidata.Why must the reset handler loop forever if main() returns?
On Cortex-M, which direction does the stack grow and where does _estack point?
_estack = top of RAM (highest address + 1), loaded into MSP.What real-world bug appears if you forget to zero .bss?
Why is the stack pointer the very first thing initialized?
Recall Feynman: explain to a 12-year-old
Imagine you build a robot and switch it on. The robot's brain wakes up totally blank — it doesn't even know where its notebook (memory) is. Startup code is a little checklist the robot runs first:
"Where's my notebook to scribble notes? → grab the stack."
"Copy my starting facts from the permanent book (Flash) into my scribble notebook (RAM)."
"Erase the blank pages so they're truly empty (zero them), not full of old smudges."
Only after this tidy-up does the robot start its real job (main). Skip the checklist and the robot reads smudges as facts and goes haywire.
Connections
- Linker scripts and memory sections (.text .data .bss)
- ARM Cortex-M exception and interrupt model
- Stack vs Heap memory layout
- The C runtime and crt0
- Bootloaders and VTOR relocation
- Volatile, memory-mapped registers and hardware init
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Socho tumne ek microcontroller power-on kiya. CPU bilkul blank hota hai — usse pata hi nahi ki main() kahan hai, variables kahan rakhne hain, ya stack kaha hai. Startup code wahi chhota sa assembly + C ka pul hai jo bare silicon ko ek complete C environment de deta hai. Teen kaam: vector table (kahan se start karna hai bataao), reset handler (RAM ko ready karo), aur stack initialization (function calls kaam karein).
Cortex-M par hardware reset par sabse pehla word memory se padhta hai aur usse MSP (stack pointer) me daal deta hai — kyunki stack to sabse pehle chahiye, interrupt aaye to registers push karne ke liye bhi. Dusra word PC me jaata hai, jo Reset_Handler ka address hai. Yahin se tumhara code chalna shuru hota hai. Vector table bas addresses ka array hai — interrupt aaye to hardware seedha index karta hai, koi search nahi.
Reset handler ka main kaam: .data (jaise int g = 42;) ki initial values Flash se RAM me copy karo, aur .bss (jaise int z;) ko zero kar do. Power-up par RAM me garbage hota hai, isliye agar .bss zero nahi kiya to ek board pe chalega, dusre pe crash — classic heisenbug. Stack RAM ke top se neeche ki taraf badhta hai (full-descending), aur heap neeche se upar — taaki dono beech me takrayein to overflow ek clear failure ban jaaye.
Yaad rakho mnemonic: Stack, Copy, Zero, Main — pehle stack set, phir data copy, phir bss zero, phir main. Yeh chhoti si glue layer hi C ke saare assumptions sach banati hai; ise skip kiya to program shuru hone se pehle hi galat.