---
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` |