On 03/11/17 04:11, stephen lu wrote: > I read article about GCC Inline Assembler > (http://www.ethernut.de/en/documents/arm-inline-asm.html). > > In this article, "memory" Clobber forces the compiler to store all > cached values before and reload them after executing the assembler > instructions. And it must retain the sequence. > > this is the example. > The following code intends to multiply c with b, of which one or both > may be modified by an interrupt routine. Disabling interrupts before > accessing the variables and re-enable them afterwards looks like a > good idea. > > > This may fail. Because the optimizer may decide to do the > multiplication first and then execute both inline assembler > instructions or vice versa. : > asm volatile("mrs r12, cpsr\n\t" > "orr r12, r12, #0xC0\n\t" > "msr cpsr_c, r12\n\t" ::: "r12", "cc"); > c *= b; /* This may fail. */ > asm volatile("mrs r12, cpsr\n" > "bic r12, r12, #0xC0\n" > "msr cpsr_c, r12" ::: "r12", "cc"); > > > This is safe by adding "memory" Clobber . > asm volatile("mrs r12, cpsr\n\t" > "orr r12, r12, #0xC0\n\t" > "msr cpsr_c, r12\n\t" :: : "r12", "cc", "memory"); > c *= b; /* This is safe. */ > asm volatile("mrs r12, cpsr\n" > "bic r12, r12, #0xC0\n" > "msr cpsr_c, r12" ::: "r12", "cc", "memory"); > > > But I disassemble code by objdump -d . "memory" Clobber don't works, > the code is to do execute both inline assembler instructions, and then > do the multiplication. > > mrs ip, CPSR > orr ip, ip, #192 ; 0xc0 > msr CPSR_c, ip > mrs ip, CPSR > bic ip, ip, #192 ; 0xc0 > msr CPSR_c, ip > mul r0, r1, r0 > mov pc, lr > > > Can anyone help me? Yes - read the next paragraph in the webpage you referenced. It tells you how to add dummy dependencies to the assembly lines to force the ordering. A memory clobber will only force ordering if the variables involved ("b" and "c" in this case) are in memory. That is implied in the example on the page, since they "may be modified by an interrupt routine" - but it will not be the case if you just declared them locally in a function. The version giving the dependencies on "b" and "c" explicitly is not only more efficient, it is also correct - wherever "b" and "c" might be located. The webpage is, IMHO, not a good reference. It gets a lot of things wrong - or at least, gives poor examples and poor suggestions. So be careful not to copy too much from it. The example here is fine as an example of how to enforce ordering using inline assembly - it is /not/ a good example of how to handle data that can be changed in an interrupt, and it is not a good example of how to disable interrupts on an ARM. It gives the impression that the compiler's optimiser is an enemy to fight - in fact, it is a partner to work together with. It gives the impression that inline assembly is a useful tool for getting optimal code - it is rare that it is the correct tool for the job. In most cases, the compiler will do a better job than you will get from handwritten assembly (especially if you use a newer version of gcc). Inline assembly in gcc is like playing with a chainsaw. It can be fun, and it is the ideal tool for some jobs - but it can be dangerous, and you should be sure it makes sense before you fire it up.