inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

ARM Cortex-M 프로세서 프로그래밍

s337_인라인 어셈블러

인라인 어셈블러 질문드립니다.

531

chltnckd7

작성한 질문수 9

1

  1.  

    인라인 어셈블러 포맷에서 ::: 마지막란에 Clobber list가 온다고 배웠습니다.

Clobber list에 "memory"를 쓰면 메모리 장벽이 생성된다는게 어떤 의미인지 구체적으로 알 수 있을까요?

 

  1. 강의 예시로 나온 코드의 내용입니다.

    (strexb %0, %2 %1" : "=&r"(result), "=Q"(*addr): "r" ((uint32_t)value));

    어셈블러 문법상 :::는 무조건 적어야한다고 강의를 통해 배웠는데요. 위 코드에서는 ' : ' 가 2개 뿐인걸로 확인했습니다. 특정 상황에서는 ' : '를 3개 다 적지 않아도 되는건가요?

     

    감사합니다~

     

임베디드 arm-architecture cortex

답변 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

chltnckd7

__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

0

chltnckd7

아.. 메모리를 사용한 거였네요.. 감사합니다.

막상 배운 어셈블리 언어들 인라인어셈블리로 작성해보려니 쉽지 않네요~

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