inline assembly는 상위 레벨 언어로된 코드의 중간에 Assembly  코드를 사용 할 수 있게해준다.

 inline assembly 는 __asm__() 안에 들어가며, 네 가지 항목으로 이루어져 있다.

    __asm__ __volatile__("@ atomic_set\n"        - (1)

"1: ldrex   %0, [%1]\n"

"   strex   %0, %2, [%1]\n"

"   teq %0, #0\n"

"   bne 1b"

    : "=&r" (tmp)                                                  - (2)

    : "r" (&v->counter), "r" (i)                             - (3)

    : "cc");                                                             - (4)




(1) 어셈블리 문장(assembly statement)( :  "" 안에 어셈블리 코드를 작성하며 각 어셈블리 문장은 newline (\n)  으로 구분된다.

(2)  출력 (output) : 어셈블리 코드에서 출력용으로 사용하는 레지스터/메모리 주소를 변수와 연결 시켜준다. 여러개를 지정할 수 있으며 각 항목은 쉼표 (',') 로 구분된다. 

(3) 입력 (input) : 어셈블리 코드에서 입력으로 사용하는 레지스터/메모리 주소를 변수와 연결시켜 준다. 여러개를 지정할 수 있으며 각 항목은 쉼표(',')로 구분된다.

(4) 변경된 레지스터( registers-modified 또는 clobbered registers) : 어셈블리 코드에서 컴파일러가 모르는 사이에 바뀔 수 있는 레지스터의 목록을 기술한다. 각 항목은 "" 안에 들어가며, 여러개의 항목을 넣을 때에는 쉼표(',')로 구분한다. 메모리에 있는 변수의 값을 수정하는 경우 "memory"라고 기술해주어야 한다.

특히,  cpu status flags 의 수정이 발생되는 명령어(ex. adds, strex)가 있을경우 clobbered list 에 "cc" 를 명시하며,
memory 의 내용을 수정하는 명령이 있을경우(ex. str) clobbered list 에 "memory"를 명시한다.

 그렇다면 왜  inline assembly 를 사용 해야할까?? 대표적으로 inline assembly 가 사용되는 상황을 정리하면
(1) Lwo Level 을 직접 다룰때 : 특히 ARM 에서 MSR, MRS 명령어와 같이 코프로세서를 제어 하기 위한 전용 명령어들을 사용해야 할때.

(2)  원자적 연산을 하려고 할때 : 특히 스핀락, 세마포의 값의 변경은 원자적으로 이루어져야 한다. ldrex strex 명령어와 같이 원자적 연산(all or nothing)을 C언어로는 구현 할 수 없다.

(3) 특정 레지스터를 직접 다뤄야 할때 : ARM 에서 범용 레지스터가 r0 ~ r12 까지 주어지는데 목적에 따라 특정 레지스터를 컴파일러의 선택이 아닌, 직접 다뤄야할때 C언어로는 불가능 하다.
 

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,