Cortex M3, "Load-Exclusive" (LDREX) ve "Store-Exclusive" (STREX) olarak adlandırılan yararlı bir çift işlem işlemini (diğer birçok makinede de yaygındır) destekler. Kavramsal olarak, LDREX işlemi bir yük gerçekleştirir, ayrıca yüklenen konumun başka bir şey tarafından yazılıp yazılmayacağını gözlemlemek için bazı özel donanımlar ayarlar. Son LDREX tarafından kullanılan adrese bir STREX uygulanması, bu adresin yalnızca önce başka bir şey yazmamışsa yazılmasına neden olur . STREX komutu, mağaza gerçekleşmişse 0 veya iptal edilmişse 1 içeren bir kayıt yükleyecektir.
STREX'in genellikle karamsar olduğunu unutmayın. Söz konusu konuma gerçekten dokunulmamış olsa bile mağazayı gerçekleştirmemeye karar verebileceği çeşitli durumlar vardır. Örneğin, bir LDREX ve STREX arasındaki bir kesinti, STREX'in izlenen konumun vurulmuş olabileceğini varsaymasına neden olur. Bu nedenle, LDREX ve STREX arasındaki kod miktarını en aza indirmek genellikle iyi bir fikirdir. Örneğin, aşağıdakine benzer bir şey düşünün:
satır içi geçersiz safe_increment (uint32_t * addr)
{
uint32_t yeni_değer;
yapmak
{
yeni_değer = __ldrex (addr) + 1;
} while (__ strex (yeni_değer, adres));
}
hangi gibi bir şey derler:
; Varsayalım ki R0 söz konusu adresi tutuyor; r1 çöp kutusuna gönderildi
lp:
ldrex r1, [r0]
r1, r1, # 1 ekle
strex r1, r1, [r0]
cmp r1, # 0; Sıfırdan farklı olup olmadığını test edin
bne lp
.. kod devam ediyor
Kodun yürütüldüğü zamanın büyük çoğunluğu, LDREX ve STREX arasında bunları "rahatsız etmek" için hiçbir şey olmayacak, bu nedenle STREX daha fazla uzatmadan başarılı olacaktır. Bununla birlikte, LDREX veya ADD komutunun hemen ardından bir kesme gerçekleşirse, STREX depoyu gerçekleştirmez, bunun yerine kod [r0] 'nin (muhtemelen güncellenmiş) değerini okumak ve yeni bir artan değeri hesaplamak için geri döner buna dayanarak.
Safe_increment gibi işlemler oluşturmak için LDREX / STREX kullanmak, yalnızca kritik bölümleri yönetmekle kalmaz, aynı zamanda birçok durumda bunlardan kaçınmayı da mümkün kılar.