Cortex M3은 "Load-Exclusive"(LDREX) 및 "Store-Exclusive"(STREX)라고하는 유용한 작업 조작 (다른 많은 머신에서도 공통)을 지원합니다. 개념적으로 LDREX 작업은로드를 수행하고로드 된 위치가 다른 것에 의해 쓰여질 수 있는지 여부를 관찰하기 위해 특정 하드웨어를 설정합니다. 마지막 LDREX에 사용 된 주소에 STREX를 수행하면 다른 주소를 먼저 쓴 경우에만 해당 주소가 기록 됩니다 . STREX 명령어는 저장이 발생한 경우 0으로, 또는 중단 된 경우 1로 레지스터를로드합니다.
STREX는 종종 비관적입니다. 실제로 해당 위치를 건드리지 않았더라도 매장을 운영하지 않기로 결정하는 다양한 상황이 있습니다. 예를 들어, LDREX와 STREX 사이의 인터럽트는 STREX가 감시중인 위치에 도달했다고 가정합니다. 이러한 이유로 LDREX와 STREX 사이의 코드 양을 최소화하는 것이 좋습니다. 예를 들어 다음과 같은 것을 고려하십시오.
인라인 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; 0이 아닌지 테스트
bne lp
.. 코드는 계속
코드가 실행되는 대부분의 시간 동안 LDREX와 STREX 사이에 "방해"가 발생하지 않으므로 STREX는 더 이상 어려움없이 성공할 수 있습니다. 그러나 LDREX 또는 ADD 명령 바로 다음에 인터럽트가 발생하면 STREX는 저장을 수행하지 않지만 대신 코드는 [r0]의 (업데이트 된) 값을 읽고 새로운 증분 값을 계산하기 위해 되돌아갑니다. 그것을 기반으로합니다.
safe_increment와 같은 연산을 형성하기 위해 LDREX / STREX를 사용하면 중요한 섹션을 관리 할 수있을뿐만 아니라 여러 섹션에서이를 피할 수 있습니다.