FraPaola tu stai compilando con gcc un eseguibile che gira sotto un sistema operativo.
Io sto compilando con ARM su un microcontrollore.... parliamo di due cose diverse. Sui microcontrollori i thread si possono gestire ma con altri sistemi e comunque sai sempre qual'è il codice da assegnare al thread e quello che deve essere eseguito con priorità. Oltre a ciò, anche per il codice in thread, NON viene assolutamente modificato MAI l'ordine di esecuzione.
Quando programmi un microcontrollore devi gestire periferiche a bassissimo livello (timing UART, I2C, PWM, ADC, DAC, DMA....); se il compilatore cambiasse l'ordine di esecuzione come dici tu tutta questa roba non funzionerebbe.
Per dirla tutta, il disassembly del codice che porti come esempio avviene perché oggi i compilatori sono più "smart" e quindi decidono che tu hai fatto un errore inizializzando la variabile "b" successivamente all'operazione e lo correggono.
Ai tempi in cui ho studiato io informatica questa roba non esisteva e, per come la vedo io, non dovrebbe esistere nemmeno adesso. Linguaggi come il visual basic, ad esempio, sono un insulto all'informatica.... la macchina deve fare ciò che dico io, non quello che dice lei. In questo modo possiamo imparare dai nostri errori che è l'unica cosa che (per ora) distingue le macchine dall'uomo.... in pratica, il tuo "ni", per una macchina, non dovrebbe esistere. 0 o 1, "si" o "no".
Ovviamente l'ultimo paragrafo è in onore dello zio....