Cortex M3 підтримує корисну пару операцій операцій (поширених також у багатьох інших машинах) під назвою "Ексклюзивний навантаження" (LDREX) та "Ексклюзивний магазин" (STREX). Концептуально операція LDREX виконує навантаження, а також встановлює якесь спеціальне обладнання, щоб спостерігати, чи може завантажене місце може бути записане чимось іншим. Виконання STREX до адреси, використовуваної останньою LDREX, призведе до того, що ця адреса буде записана, лише якщо спочатку нічого іншого не написав . Інструкція STREX завантажить реєстр з 0, якщо магазин відбувся, або 1, якщо він перерваний.
Зауважте, що STREX часто песимістичний. Існує безліч ситуацій, коли це може вирішити не працювати в магазині, навіть якщо б фактично не торкнулося відповідного місця. Наприклад, переривання між LDREX і STREX призведе до того, що STREX припустить, що місце, яке спостерігається, може бути потрапило. З цієї причини зазвичай корисно мінімізувати кількість коду між LDREX та STREX. Наприклад, розгляньте щось подібне:
inline void safe_increment (uint32_t * addr)
{
uint32_t new_value;
робити
{
new_value = __ldrex (addr) + 1;
} while (__ strex (new_value, addr));
}
яка компілює щось на зразок:
; Припустимо, що R0 має вказану адресу; r1 пошкоджено
lp:
ldrex r1, [r0]
додайте r1, r1, # 1
strex r1, r1, [r0]
cmp r1, # 0; Перевірте, чи немає нуля
bne lp
.. код продовжується
Переважна більшість часу виконання коду між LDREX і STREX нічого не відбудеться, щоб "потривожити" їх, тому STREX матиме успіх без подальшої помилки. Якщо, однак, після вказівки LDREX або ADD трапиться переривання, STREX не виконає магазин, а натомість код повернеться до зчитування (можливо оновленого) значення [r0] та обчислить нове збільшення значення виходячи з цього.
Використання LDREX / STREX для формування таких операцій, як safe_increment, дає змогу не тільки керувати критичними розділами, але й у багатьох випадках уникати потреби в них.