My code
while(usart_transmit_status); usart_transmit_status = 1;
translate at -O0
0x08001EB4 4807 LDR r0,[pc,#28] ; @0x08001ED4 0x08001EB6 7800 LDRB r0,[r0,#0x00] 0x08001EB8 2800 CMP r0,#0x00 0x08001EBA D1FB BNE 0x08001EB4
and translate at -O1
0x08001A6E 4907 LDR r1,[pc,#28] ; @0x08001A8C 0x08001A70 7808 LDRB r0,[r1,#0x00] 0x08001A72 2800 CMP r0,#0x00 0x08001A74 D1FD BNE 0x08001A72
It leads to an error because R0 changes in interruption
#pragma push #pragma O0 while(usart_transmit_status); usart_transmit_status = 1; #pragma pop
No effect
Solved by declare the variable usart_transmit_status as volatile
volatile
Just for the record: I believe you have the two compiler outputs the wrong way round. The -O1 version looks exactly like -O0 code would: ponderously re-doing every single step of the loop, without the slightest consideration for efficiency. The code you show as -O0 has received a bit of optimization: steps that (for non-volatile input) would yield the exact same result every time have been short-circuited.
I adjusted my post