I have modified the code as follows: #include <stdio.h> #define barrier() __asm__ __volatile__("": : :"memory") int main() { int i, n; int s = 0; int *p; scanf("%d", &n); for (i = 0; i < n; i++) s += i; barrier(); p = &s; <--- for s, the & operator is used printf("%d %d %d\n", i, n, *p); <--- the s is referenced through a pointer return 0; } and the corresponding asm code is as follows: leal -8(%ebp), %eax pushl %eax pushl $.LC0 call scanf movl -8(%ebp), %edx addl $16, %esp testl %edx, %edx jg .L2 movl $0, %eax movl $0, %ecx jmp .L4 .L2: movl $0, %eax movl $0, %ecx .L5: addl %eax, %ecx incl %eax cmpl %edx, %eax jne .L5 .L4: <--- after the barrier(() pushl %ecx <--- In spite of using the '&' operator, the value of s is still gotten from the register rather than the corresponding memory location. pushl -8(%ebp) <--- the value of n is gotten from its memory location indeed pushl %eax pushl $.LC1 call printf Alough the '&' operator is used for both 's' and 'n', gcc deals with them differently. The former's value is in a register, while the latter's value is retrieved from the corresponding memory location. I wonder the difference. 2010/12/22 Andrew Haley <aph@xxxxxxxxxx>: > On 12/22/2010 03:16 PM, Parmenides wrote: >> >> Hi, >> >> According to the gcc's manual, in an extended assembly statement, >> if the string "memory" is added to the list of of clobbered registers, >> it will cause "gcc to not keep memory values cached in registers >> across the assembler instrution and not optimize stores or loads to >> that memory". To this end, IMO, after this kind of statement all >> values cached in registers should be write into the corresponding >> memory locations. But, the following example illustrates some >> different thing. >> >> #define barrier() __asm__ __volatile__("": : :"memory") >> >> int main() >> { >> int i, n; >> int s = 0; >> >> scanf("%d",&n); >> for (i = 0; i< n; i++) >> s += i; >> barrier(); >> printf("%d\n", s); >> >> return 0; >> } >> >> # gcc -S -O tst.c >> >> We get the assembly code like this: >> >> leal -8(%ebp), %eax >> pushl %eax >> pushl $.LC0 >> call scanf >> movl -8(%ebp), %edx<--- cache n into edx >> addl $16, %esp >> testl %edx, %edx >> jg .L2 >> movl $0, %ecx >> jmp .L4 >> .L2: >> movl $0, %eax<--- cache i into eax >> movl $0, %ecx<--- cache s into ecx >> .L5: >> addl %eax, %ecx >> incl %eax >> cmpl %eax, %edx >> jne .L5 >> .L4: >> <--- at this point, I think the barrier() will cause the values cached >> in edx, eax and ecx will be write back to n, i, and s, respectively. >> But, this is not really the case. >> >> subl $8, %esp >> pushl %ecx >> pushl $.LC1 >> call printf > > Well, i and s never have their address taken, so they are not forced > into memory, and the memory clobber can't affect them. > > Andrew. >