--- title: ByteWise - Breakdown the Minimal Bootloader for Cortex-M tags: bytewise, --- # Breakdown the Minimal Bootloader in Cortex-M ```c static void start_app(void *pc, void *sp) { __asm( " \n\ msr msp, r1 \n\ bx r0 \n\ " ); } int main() { ... start_app(app_vectors->pfnReset_Handler, app_vectors->pvStack); while(1) // should never be reached } ``` This is a mininal bootloader codes, in `main`, it call `start_app` with two parameters, - `app_vectors->pfnReset_Handler`: **the pointer to the application's `ResetHandler`** - `app_vectors->pvStack` : **the pointer to the start address of the stack**. In the `start_app(...)`, it reconfigure the **Main Stack Pointer**, `msp` to the ***sp*** and jumps to where ***pc*** points to, that is, the `ResetHandler()` of the application. :::success :question: It still unclear to me why it use `r0` and `r1` in the inlined assembly instead of using `pc` and the `sp` directly? On top of this, why `r0` and `r1` represent the two arguments? :::danger > [10.1 Passing Arguments in Registers](https://bob.cs.sonoma.edu/IntroCompOrg-RPi/sec-reg-use.html#p-1645), *Introduction to Computer Organization: ARM Assembly Language Using the Raspberry Pi* by Robert G. Plantz > When one C function calls another, only the **first four** arguments to the called function are passed in registers. Reading a C argument list from left to right, the following table shows the order in which the arguments are stored in the registers. **If more arguments need to be passed, they are stored on the stack**. | Argument | Register | | -------- | -------- | | arg1 | `r0` | | arg2 | `r1` | | arg3 | `r2` | | arg4 | `r3` |