This is my C code
void user_main(void)
{
u32 asd;
osGetSysCnt(&asd);
}
This is the disassembly
void user_main(void)
{
10040230: b507 push {r0, r1, r2, lr}
u32 asd;
osGetSysCnt(&asd);
10040232: a801 add r0, sp, #4
10040234: f000 f801 bl 1004023a <osGetSysCnt>
}
10040238: bd07 pop {r0, r1, r2, pc}
Why is the stack pointer incremented? Wouldn't that override the already pushed registers?
Why is the stack pointer incremented? Wouldn't that override the already pushed registers?
No, because sp
is not incremented in the disassembly code.
10040232: a801 add r0, sp, #4
Purpose of add
: The add
instruction calculates the memory address relative to the current value of sp (stack pointer). Here, add r0, sp, #4
computes the address sp + 4
, which points to the location of the variable asd
on the stack.
The resulting address is stored in r0
, which is then passed as a parameter to osGetSysCnt
.
Isn't ARM stack full descending? Meaning sp+4 refers to the already pushed at the start registers.
It is. The push
instruction is creating the stack frame sufficient for the function needs. The compiler does not care about what was there as ABI specifies that those registers do not have to be preserved. So this push
is not preserving anything.
Why does the compiler use push
instruction? It indicates that you are compiling with size optimizations enabled (-Os
). push
is short but time-consuming. If you change the optimization level to optimize for speed (-Ofast
, -O2
, -O3
) the compiler will emit different code:
str lr, [sp, #-4]!
ldr r3, .L4
sub sp, sp, #12
add r0, sp, #4
str r3, [sp, #4]
bl osGetSysCnt
add sp, sp, #12
ldr lr, [sp], #4
bx lr