Cortex M3 รองรับการทำงานของการดำเนินงานคู่ที่มีประโยชน์ (ทั่วไปในเครื่องอื่น ๆ อีกมากมาย) เรียกว่า "Load-Exclusive" (LDREX) และ "Store-Exclusive" (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;
} ขณะที่ (__ 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 ทำให้ไม่เพียง แต่จะจัดการส่วนที่สำคัญเท่านั้น แต่ในหลาย ๆ กรณีเพื่อหลีกเลี่ยงความต้องการเหล่านั้น