인라인 어셈블러 질문드립니다.
531
작성한 질문수 9
인라인 어셈블러 포맷에서 ::: 마지막란에 Clobber list가 온다고 배웠습니다.
Clobber list에 "memory"를 쓰면 메모리 장벽이 생성된다는게 어떤 의미인지 구체적으로 알 수 있을까요?
강의 예시로 나온 코드의 내용입니다.
(strexb %0, %2 %1" : "=&r"(result), "=Q"(*addr): "r" ((uint32_t)value));
어셈블러 문법상 :::는 무조건 적어야한다고 강의를 통해 배웠는데요. 위 코드에서는 ' : ' 가 2개 뿐인걸로 확인했습니다. 특정 상황에서는 ' : '를 3개 다 적지 않아도 되는건가요?
감사합니다~
답변 1
1
안녕하세요, chltnckd7님!
Q1. 인라인 어셈블러 포맷에서 ::: 마지막란에 Clobber list가 온다고 배웠습니다.
Clobber list에 "memory"를 쓰면 메모리 장벽이 생성된다는게 어떤 의미인지 구체적으로 알 수 있을까요?
A1. 컴파일 과정에서 컴파일러는 최적화를 위해 필요한 경우 사용자 작성 코드를 재배치(Reordering)할 수 있습니다. 게다가 캐쉬, 레지스터를 사용하는 경우까지 가세하게 되니까 이는 시스템의 각 요소들 사이의 메모리 연산의 순서에 대한 보장이 굉장히 어렵고 중요한 문제가 될 수 있습니다. 이에 메모리 장벽이라는 기술을 사용할 수 있는데, DMB, DSB, ISB 와 같은 메모리 장벽을 위한 어셈블리 명령어를 사용할 경우 이를 통해 명령어의 사용전 코드 블럭과 사용 후의 코드 블럭사이에서의 메모리 연산의 실행 순서를 보장할 수 있습니다.
e.g. 클로버(memory)가 사용된 코드의 예
__STATIC_FORCEINLINE void __enable_irq(void){
__ASM volatile ("cpsie i" : : : "memory");
}
코드 블럭 A 영역
__enable_irq(); // 이 함수 호출을 기준으로 앞선 코드 블럭 A 영역에서의 메모리 관련 동작이 완전히 끝나야만, 코드 블럭 B의 실행이 진행된다.
코드 블럭 B 영역
메모리 장벽에 관련하여 자세한 것은 다음의 글을 참고하면 좋습니다.
Q2. 강의 예시로 나온 코드의 내용입니다.
(strexb %0, %2 %1" : "=&r"(result), "=Q"(*addr): "r" ((uint32_t)value));
어셈블러 문법상 :::는 무조건 적어야한다고 강의를 통해 배웠는데요. 위 코드에서는 ' : ' 가 2개 뿐인걸로 확인했습니다. 특정 상황에서는 ' : '를 3개 다 적지 않아도 되는건가요?
A2. 아래 시놉시스처럼 콜론은 입출력 오퍼랜드와 클로버가 작성된 상태에 따라 다릅니다.
asm asm-qualifiers ( AssemblerTemplate : OutputOperands [ : InputOperands [ : Clobbers ] ] )
클로버가 인라인어셈블리에 표현되어 있다면 콜론 기호는 3개가 필요하지만, 표현된 문장에 클로버가 생략되어 있다면 콜론 기호는 2개 이하이겠지요. 자세한 내용은 아래 예시를 참조 바랍니다.
e.g. 클로버를 사용한 예( 콜론 3개 )
__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control){
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
}
e.g. 클로버를 사용하지 않은 예( 콜론 2개 )
__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control){
__ASM volatile ("MSR control, %0" : : "r" (control));
}
0
__STATIC_FORCEINLINE int MOV_TEST(volatile int *val1)
{
int result;
__ASM volatile( "MOV %0, %1" : "=r"(result) : "Q"(*val1) );
return result;
}
mov를 인라인 어셈블리로 위와 같이 작성 하였는데 해당 오류가 나옵니다.
오류 내용 :
Error: undefined symbol r3 used as an immediate value
일반 변수를 사용하면 잘 되는데 포인터로 작성하면 오류가 생기네요. 왜 이런 걸까요?
혹시나 __ASM volatile( "MOV %0, [%1]" : "=& r"(result) : "r"(val1) ); 이렇게 작성해도 오류가 나오네요.
0
mov 명령의 오퍼랜드에는 메모리를 사용할 수 없습니다. 레지스터나 상수만이 가능하죠.
예를들어, mov r0,r1 혹은 mov r0,#4
그러므로 코드는 다음과 같이 작성되어야 합니다.
__STATIC_FORCEINLINE int MOV_TEST(volatile int* val1)
{
int result;
__ASM volatile( "ldr %0, %1" : "=r"(result) : "Q"(*val1) );
return result;
}
printf("ret=%#x\n", MOV_TEST(&a));
===
실행결과
ret=0x12345678
stm32cubeide 관련 문의
0
53
2
DMA 관련한 강의도 제작해주실 수 있으신가요 ?
0
100
1
그림들도 해석 할 수 있어야 하나요?
1
103
2
no-stlink
1
82
2
4개의 CPU 사이클이 필요한 이유
1
101
2
MAC으로 진행 질문드려요..
1
95
2
학습 진행 시, 사용하는 Board에 대한 문의 드립니다!
0
160
2
push pop 질문
1
192
2
STM32Fx Cortex ARM 프로그래밍 저자:홍봉조, 출판사:지식과 감성
0
242
1
CORTEX_02_ASSEMBLY 빌드시 에러
1
270
1
외부 ST Link 연결 이용한 SWD 방법
0
343
1
파이프라인과 명령어
1
327
1
명령어 fetch
0
238
1
lr 레지스터 LSB 값
1
261
1
Disassembly 창 문제
0
350
1
s702 강좌에서 사용한 technical reference manual 문서
1
328
1
s702에 원자적 Access 를 위한 BSRR 코드작성 부분에 대해서
1
274
1
s202 LED 점등 예제 실행시 에러
2
351
1
STM32F429I-DISC 보드의 펌웨어
2
395
1
제공되지 않은 강의교재
0
319
1
s524 테일체이닝 강의 질문
0
235
1
부트코드와 부트로더의 차이점
1
1531
1
메모리 맵 질문
0
288
1
xPSR 레지스터 플래그 값 및 기타 질문 드립니다.
1
864
2





