Notes / Machine Code & Assembly
C against assembly: what optimisation options change
Disassemble a simple C function and match it line by line, then compare how differently -O0 and -O2 build the same code.
How to view a disassembly
arm-none-eabi-objdump -d -S firmware.elf > fw.lst
With -S the C source and the instructions are interleaved. In STM32CubeIDE, open the Disassembly window while debugging.
The same function, different results
int sum(const int *a, int n) {
int s = 0;
for (int i = 0; i < n; i++) s += a[i];
return s;
}
- -O0: the variables
sandiare stored to the stack and read back every time. Good for debugging, but slow. - -O2:
sandistay in registers, and the loop runs by incrementing the pointer directly. The instruction count falls to less than half.
Bugs that optimisation exposes
If behaviour goes wrong only at -O2, it is usually one of these.
- No
volatileon a variable shared with an interrupt → the read is hoisted out of the loop - Undefined behaviour (signed overflow, uninitialised variables)
- A delay loop
for (i = 0; i < 1000; i++);vanishes entirely
Read it not as "optimisation breaks things" but as "optimisation exposed a bug that was already there".