Here we see that the `reset_handler` intitates static heap variables (by 0 or value accordingly) before calling `main` (and puts the processor in sleep mode in case `main` returns). The user `main` has the symbol `bare0::main`, which is unknown to the `cortex-m-rt` library (defining the generic `reset_handler`). Hence the, `reset_handler` calls a compiler generated (trampoline)`main`, that in turn calls`bare0::main` (the user `main`).
Here we see that the `reset_handler` intitates static heap variables (by 0 or value accordingly) before calling `main` (and puts the processor in sleep mode in case `main` returns). The user `main` has the symbol `bare0::main`, which is unknown to the `cortex-m-rt` library (defining the generic `reset_handler`). Hence the, `reset_handler` calls a compiler generated start item`main`, that in turn trampolines to`bare0::main` (the user `main`).
The compiler has optimized away ALL your code!!! (`8000476: e7fe b.n 8000476` implements an infinite loop). Why you might ask, well it figures out that your the program has no *observable* effect (it will not output or change anything).
We can make a small change to the program (violating the assertion, by commenting out `X += 1;`. After compilation the oject dump of user main looks like this:
So the Rust compiler is able to figure out that the assertion will be violated and merely calls the `panic` routine. So be aware, the Rust compiler is extremely aggressive in optimizing your code. On a side note the semantics of integer additions is slightly different between `dev` (normal/non-optimized) and `--release` (optimized) builds. In `dev` build the arithmics are checked and overflows result in a `panic`, in `--release`, arithmetics are unchecked (for performance reasons), and oveflows wrap (under two's complement semantics). To avoid ambiguity, you may use methods defined in the std/core library:
- `wrapping_add`, `wrapping_sub`,returns the straight two’s complement result,
- `saturating_add`, `saturating_sub`, returns the largest/smallest value (as appropriate) of the type when overflow occurs,
- `overflowing_add`, `overflowing_sub`, returns the two’s complement result along with a boolean indicating if overflow occured, and
- `checked_add`, `checked_sub`, returns an `Option` that’s `None` when overflow occurs, and `Some(v)` elsewise.
Those methods never `panic`, but code might be verbose, e.g., expressing `x - y + z` under wrapping arithmetics equates to `x.wrapping_sub(y).wrapping_add(z)`. To this end you may choose to use the [Wrapping](https://doc.rust-lang.org/std/num/struct.Wrapping.html) type.