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

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -

java - Digest auth with Spring Security using javaconfig -