Consider this eg:
1 int main(void){
2 int a, x, y;
3 x=a;
4 y=a;
5 }
Line 3 with be converted to a LDR instruction.
Line 4 is where the compiler optimization comes in. It may be loaded from the
previous loaded register.
Line 3: ldr r0[r1]; r1 is having the address of a
Line 4: mov r2 r0; because we have value of a already in r0.
But if a is a volatile vairable, then compiler places ldr for both instructions( for x=a and y=a)
So Line 4 will change as follows,
Line 3: ldr r0[r1]; r1 is having the address of a
Line 4: ldr r2[r1]; r1 is having the address of a
But if cache is enabled for these memory region, with the first ldr, data is cached. Now second ldr can fetch the data from cache. So using just volatile is not sufficient. Proper MMU mappings(non cached mapping in this case) is a must.
So Line 4 will change as follows,
Line 3: ldr r0[r1]; r1 is having the address of a
Line 4: ldr r2[r1]; r1 is having the address of a
But if cache is enabled for these memory region, with the first ldr, data is cached. Now second ldr can fetch the data from cache. So using just volatile is not sufficient. Proper MMU mappings(non cached mapping in this case) is a must.