This isn't actually true IMHO, all of this is easily controlled using the volatile qualifier in C.
Nice post, overall, but 'volatile' is not always enough. The thing is that some hardware setup, has strict timing 'rules', imposed by the datasheet and/or hardware design.
E.g. An A to D converter, which insists, that after enabling it, you have to wait X microseconds or machine cycles, before using it. So that it can stabilise/initialise itself properly.
Or a watch-dog timer(s), which can only be enabled or disabled, a certain time (e.g. clock cycles), after initially coming out of reset. To stop errant software from being able to interfere with the watch-dog timer, later.
In assembler, these timings, are fairly easily bolted down, by counting the clock cycles (which isn't necessarily that precise these days, as already discussed in this thread).
But in a highly optimised compiler (although one option, might be to disable or reduce the optimisation setting, for the hardware initialisation part of the code). The compiler may interfere too much with the timings. Bit-banging, hardware timings, can also be tricky, when compiler optimisations are enabled.
In some extreme cases (I remember worrying about this a long time ago, I can't remember if I had to do it or not, in the end). Even the initialisation performed by the C compiler (e.g. clearing sections of memory, compiler dependent), can take so long (in fast hardware terms, like milliseconds). That you can't meet the specifications of the product, without putting assembler start up code, even BEFORE the C code has initialised itself.
Even before the first C statement, can be executed.
E.g. To check for some startup options (defined by the statues of some external I/O port pins), then do things and/or disable/enable other I/O things. To meet those requirements.
I can't remember exactly, but off the top of my head, it was something worrying long, like 500 milliseconds (on a relatively slow processor, too long ago, I could be misremembering, but it was longish), to finish the C compiler initialisations.
It was to switch on or off, some stuff, to protect the hardware, immediately after switch on (coming out of reset). Otherwise, the hardware could damage itself (arguably poor design, not my design anyway).
Anyway, I agree. that there are various things you can do, so that if you are really determined. You can solve most/all of these issues and implement such schemes in C code.
E.g. Using hardware timers and/or interrupts. To get the timing right and independently of the instruction execution times.