Cortex M3 hỗ trợ một cặp hoạt động hữu ích (cũng phổ biến trong nhiều máy khác) được gọi là "Tải độc quyền" (LDREX) và "Độc quyền lưu trữ" (STREX). Về mặt khái niệm, hoạt động LDREX thực hiện tải, cũng đặt một số phần cứng đặc biệt để quan sát xem vị trí đã tải có thể được ghi bởi một thứ khác hay không. Việc thực hiện STREX đến địa chỉ được sử dụng bởi LDREX cuối cùng sẽ khiến địa chỉ đó chỉ được ghi nếu không có gì khác được viết trước . Lệnh STREX sẽ tải một thanh ghi bằng 0 nếu cửa hàng diễn ra hoặc 1 nếu nó bị hủy bỏ.
Lưu ý rằng STREX thường bi quan. Có nhiều tình huống trong đó nó có thể quyết định không thực hiện cửa hàng ngay cả khi vị trí được đề cập trên thực tế không bị chạm vào. Ví dụ: một ngắt giữa LDREX và STREX sẽ khiến STREX cho rằng vị trí đang theo dõi có thể đã bị tấn công. Vì lý do này, thông thường nên giảm thiểu số lượng mã giữa LDREX và STREX. Ví dụ, hãy xem xét một cái gì đó như sau:
nội tuyến void safe_increment (uint32_t * addr)
{
uint32_t new_value;
làm
{
new_value = __ldrex (addr) + 1;
} while (__ strex (new_value, addr));
}
mà biên dịch thành một cái gì đó như:
; Giả sử R0 giữ địa chỉ trong câu hỏi; thùng rác r1
lp:
ldrex r1, [r0]
thêm r1, r1, # 1
strex r1, r1, [r0]
cmp r1, # 0; Kiểm tra nếu khác không
bne lp
.. mã tiếp tục
Phần lớn thời gian mã thực thi, sẽ không có gì xảy ra giữa LDREX và STREX để "làm phiền" chúng, vì vậy STREX sẽ thành công mà không cần phải quảng cáo thêm. Tuy nhiên, nếu xảy ra gián đoạn xảy ra ngay sau lệnh LDREX hoặc ADD, STREX sẽ không thực hiện lưu trữ mà thay vào đó, mã sẽ quay lại để đọc giá trị (có thể được cập nhật) của [r0] và tính giá trị gia tăng mới dựa trên điều đó
Sử dụng LDREX / STREX để hình thành các hoạt động như safe_increment giúp không chỉ quản lý các phần quan trọng mà còn trong nhiều trường hợp để tránh sự cần thiết của chúng.