[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] "Volatile"
Re: [avr-gcc-list] "Volatile"
Sun, 17 Apr 2005 10:46:44 -0500
I have had to work with software engineers who have worked in embedded
systems for several years and cannot tell you the effect of the static
modifier, let alone volatile. A popular misconception was that these
keyword affect whether or not a variable is cached (pause for
To an otherwise fine post, I would like to raise two issues:
With respect, Graham, I think you may have misunderstood the "cached"
terminology here. Obviously an AVR doesn't have large instruction or
data cache like a PowerPC or Pentium. But the compiler does cache a
variable's value into a register and re-use that register (without
loading the variable from memory again) as an optimization.
Using volatile is a directive to the compiler to always load/store that
variable from/to memory every time it is referenced in the source code.
Using volatile can then become confusing for a trivial fragment such as
volatile v = 42;
v = ((v=12) | (~v) | (!v));
Does this cause two loads of v? Is v equal to twelve or forty two when
~v is executed? Answers are left as an exercise to the reader. But
let me give this advice to all: when declaring a volatile variable, use
it only in very simple statements. In the embedded space, especially
when dealing with volatile, it is a good programming practice to break
complex actions into multiple lines of simple statements. This makes
things clear to the reader and assists debugging.
Even on this list, some of the experts are not 100% clued in. A while
asked if I was wrong to expect that an assignment to a volatile object
should result in exactly one machine-level write to the memory
which it is stored. Several responders told me that I should not
this and that the compiler is at liberty to implement the assignment as
multiple writes even when the variable is declared volatile. Further
research indicated that this was wrong and my expectation is correct.
In general, a compiler is free use any number of instructions when
translating a line of C to assembly. The compiler's goal is to use as
few instructions as possible to make execution faster. Lets take the
example "volatile v = 42;" After loading 42 into a register, this may
result in a store-direct (STS) instruction or a store-indirect (ST)
instruction. The store-indirect uses X, Y or Z as an address register.
So, would you count the instructions that put v's address into the
Also be aware that the compiler is within its right to convert the line
"v = 42;" into two, three, or N identical store instructions, even
though it is redundant. No compiler I know would do this, but one must
not rely on optimal C-to-ASM translation, only on logical behavior. If
one needs exact assembly instructions, one should write in assembly.
RE: [avr-gcc-list] "Volatile", Dave Hansen, 2005/04/15
Re: [avr-gcc-list] "Volatile", Douglas Dotson, 2005/04/15
Re: [avr-gcc-list] "Volatile", Graham Davies, 2005/04/15
RE: [avr-gcc-list] "Volatile", David Harper, 2005/04/15
Re: [avr-gcc-list] "Volatile",
Dean Hall <=
- Re: [avr-gcc-list] 'Volatile', (continued)