c - How do loops with incrementing global variables work without volatile modifier? -
i have been working on msp430g2553 using using mspgcc compiler , introductory program have begun blinking led. code have used follows:
#include <msp430.h> unsigned int i; void main(void) { wdtctl = wdtpw | wdthold; // stop watchdog timer p1dir |= 0x01; //set p1.0 output for(;;) { p1out ^= 0x01; i=0; while(i<50000) { i++; } } }
where while loop work of providing delay.
i thought since above while loop in i
increments 0 value, why can't use decrementing loop. tried following code.
#include <msp430.h> unsigned int i; void main(void) { wdtctl = wdtpw | wdthold; // stop watchdog timer p1dir |= 0x01; //set p1.0 output for(;;) { p1out ^= 0x01; i=50000 while(i>0) { i--; } } }
this code didn't work , on finding reason, came know global variable i
needs provided "volatile" prevent optimization of compiler because here value of i
can change @ time.
my question in first case value of i
changing 0 49999 why didn't use "volatile" modifier in case?
the assembler code each of cases above follows:
case 1 (incrementing loop)
main: 40b2 5a80 0120 mov.w #0x5a80,&watchdog_timer_wdtctl p1dir |= 0x01; //set p1.0 output d3d2 0022 bis.b #1,&port_1_2_p1dir p1out ^= 0x01; $c$l1: e3d2 0021 xor.b #1,&port_1_2_p1out i=0; 4382 0200 clr.w &i while(i<50000) 90b2 c350 0200 cmp.w #0xc350,&i 2ff8 jhs ($c$l1) i++; $c$l2: 5392 0200 inc.w &i 90b2 c350 0200 cmp.w #0xc350,&i 2ff2 jhs ($c$l1) 3ff9 jmp ($c$l2)
case 2 (decrementing loop)
main: 40b2 5a80 0120 mov.w #0x5a80,&watchdog_timer_wdtctl p1dir |= 0x01; //set p1.0 output d3d2 0022 bis.b #1,&port_1_2_p1dir p1out ^= 0x01; $c$l1: e3d2 0021 xor.b #1,&port_1_2_p1out i=50000; 40b2 c350 0200 mov.w #0xc350,&i while(i>0) 9382 0200 tst.w &i 27f8 jeq ($c$l1) i--; 4382 0200 clr.w &i 3ff5 jmp ($c$l1)
briefly, volatile
qualifier tells compiler object has side-effects beyond "vision". must not optimise out accesses it.
without compiler free optimise-out whole loop if can proof not change observable behaviour of program. note not guaranteed , in case compiler seems recognise 1 code pattern, not other. must not rely on (and whoever wrote code lacks fundamental coding practice).
in both cases, volatile
necessary though on safe side. note compiler still might able optimise code; best additionally put nop
assembler intrinsic loop.
note: see generated assembler code. optimised code include i = 0
instead of loop or leave i
@ default value static variables (which 0
, too).
Comments
Post a Comment