Consider this code (from experimentation with the if_ie.c driver).
// u_char *tjt; volatile u_char *tjt; tjt = (u_char *) obie; *tjt = 0; printf ( "obie 0 gives: %x\n", *tjt ); *tjt = 0xff; printf ( "obie ff gives: %x\n", *tjt );With the volatile declaration, the output is correct as:
obie 0 gives: 0 obie ff gives: F0Without the volatile declaration, we get this, which is wrong:
obie 0 gives: 0 obie ff gives: FFHere is the generated code with the volatile declaration in place:
fef7ca0: 4212 clrb %a2@ fef7ca2: 1012 moveb %a2@,%d0 fef7ca4: 0280 0000 00ff andil #255,%d0 fef7caa: 2f00 movel %d0,%sp@- fef7cac: 4879 0fef d161 pea fefd161 (format string) fef7cb2: 4e93 jsr %a3@ printf fef7cb4: 50d2 st %a2@ fef7cb6: 1012 moveb %a2@,%d0 fef7cb8: 0280 0000 00ff andil #255,%d0 fef7cbe: 2f00 movel %d0,%sp@- fef7cc0: 4879 0fef d173 pea fefd173 (format string) fef7cc6: 4e93 jsr %a3@ printfHere is the generated code without it.
fef7ca0: 4212 clrb %a2@ fef7ca2: 42a7 clrl %sp@- fef7ca4: 4879 0fef d151 pea fefd151 (format string) fef7caa: 4e93 jsr %a3@ printf fef7cac: 50d2 st %a2@ fef7cae: 4878 00ff pea ff fef7cb2: 4879 0fef d163 pea fefd163 (format string) fef7cb8: 4e93 jsr %a3@ printfThe thing to observe is that the compiler skips the readback from a2@ when we don't declare the register volatile. The compiler "knows" what it just put there (either 0 or ff), so it just passes that value to the printf() call and doesn't bother to do the readback.
In this case the 8 bit register is the "on board ethernet register" and only the 4 high bits are R/W. The 4 low bits have 2 bits wired to ground (so they will -always- read 0). The other 2 yield status values from hardware which in this case are always 0.
Tom's Computer Info / tom@mmto.org