In avr-libc manual I've fund an interesting article by Jan Waclawek abort reordering problems in gcc.
Let's look at the following code from manual:
unsigned int ivar; void test2( unsigned int val ) { val = 65535U / val; cli(); ivar = val; sei(); }
The generated assembly is as follows:
00000112: 112: bc 01 movw r22, r24 114: f8 94 cli 116: 8f ef ldi r24, 0xFF ; 255 118: 9f ef ldi r25, 0xFF ; 255 11a: 0e 94 96 00 call 0x12c ; 0x12c <__udivmodhi4> 11e: 70 93 01 02 sts 0x0201, r23 122: 60 93 00 02 sts 0x0200, r22 126: 78 94 sei 128: 08 95 ret
We can clearly see that cli was reordered. But to me the whole concept of this example is unclear. If we need an atomic access to ivar, it means that ivar can by modified or accessed in unpredictable way in other places in program, probably in interrupt routines. So ivar declaration is bad, it should be as follows:
volatile unsigned int ivar;
But in that case the generated assembly code is perfect:
volatile unsigned int ivar; void test2( unsigned int val ) { 172: bc 01 movw r22, r24 val = 65535U / val; 174: 8f ef ldi r24, 0xFF ; 255 176: 9f ef ldi r25, 0xFF ; 255 178: 0a d0 rcall .+20 ; 0x18e <__udivmodhi4> cli(); 17a: f8 94 cli ivar = val; 17c: 70 93 03 01 sts 0x0103, r23 180: 60 93 02 01 sts 0x0102, r22 sei(); 184: 78 94 sei } 186: 08 95 ret
So am I wrong and missing the point, or above example is a crap?