При написании системного ПО, не обязательно для встраиваемых систем необходимо быть уверенным, что программа скомпилирована и работает так, как написана, и "умный" компилятор при оптимизации не переставил или вообще выкинул "не нужные" на его взгляд инструкции.
Для этого применяется такая штука, как Memory Barrier.
Если мы используем GCC или GCC-совместимый компилятор, то может быть объявлен такой макрос:
#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
И тогда критические участки кода, например, работа со счетчиками блокировок планировщика в ОС могут быть
реализованы следующим образом:
HAL_REORDER_BARRIER();
shed_lock ++;
HAL_REORDER_BARRIER();
При оптимизации компилятор не анализирует код в ассемблерных макросах, поэтому когда он встречает макрос "asm" он понимает, что этот кусок оптимизировать не надо.
Кстати, Memory Barrier можно использовать и для более приземленных целей.
Например, надо записать число в регист контроллера...да хотя бы зажечь лампочку.
Делается это, например, при помощи такого макроса:
#define WriteReg(addr,val) (*(volatile unsigned*)(addr)=val);
таким образом:
WriteReg(LEDS_BASE + XGPIO_TRI_OFFSET, 0x1);
С большой долей вероятности при включении оптимизации такой код будет выкинут. В этом случае можно определить таким образом:
#define WriteReg(addr,val) \
HAL_REORDER_BARRIER(); \
(*(volatile unsigned*)(addr)=val); \
HAL_REORDER_BARRIER();
и все заработает =)
Конкретная реализация макроса HAL_REORDER_BARRIER() будет отличаться для каждого компилятора.
Более подробно про Memory Barrier можно почитать хотя бы в википедии: http://en.wikipedia.org/wiki/Memory_barrier