임베디드 레시피

Egloos | Log-in





인라인 어셈블러를 사용하려면?

뭘 알아야 이해를 하지
씨 언어로 만든 프로그램에다 어셈블러 명령어를 삽입하는 것을 인라인 어셈블러라고 해요.
인라인 어셈블러를 사용하는 목적이 무엇일까요? 우선 효율적인 프로그램을 만들 수가 있어 프로그램 속도가 향상되며, 더불어 바이너리 크기를 줄일 수가 있어 메모리 절약에도 큰 도움이 된답니다.
그럼 본격적으로 예제를 살펴보도록 할게요.
 



인라인 어셈블러를 사용하려면 우선 g-1과 같이 선언을 하면 됩니다.
기본적인 문법을 살펴볼게요.
h-1에서 j-1까지는 어셈블러 명령어랍니다. k-1은 최종 결과값이 어디에 저장될 것인가를 지정한답니다. 연산을 하기 위해 입력할 데이터를 지정하는 부분이 l-1이며 순차적으로 i, j, x, y값이 있는데 이것은 h-1의 명령어 이후 %1, %2, %3, %4에 각각 할당 받게 된답니다. h-1에서 j-1까지 덧셈을 해서 j-1에 %0지정된 변수로 저장해서, 최종 메모리에 반영 해라는 의미로 m-1 에서 선언을 했답니다.
 
[인라인 어셈블러를 컴파일했을 때 생성된 명령어]
    ___addr/line__|code_____|label____|mnemonic________________|comment
                       |
                   14|  __asm__ __volatile__ (
   SR:0000037C|E51B0010            ldr     r0,[r11,#-0x10]       // i=1값 읽음
   SR:00000380|E51B1014            ldr     r1,[r11,#-0x14]       // j=1값 읽음
   SR:00000384|E51B2018            ldr     r2,[r11,#-0x18]       // x=1값 읽음
   SR:00000388|E51B301C            ldr     r3,[r11,#-0x1C]       // y=1값 읽음
   SR:0000038C|E0800001            add     r0,r0,r1                  // i + j
   SR:00000390|E0822003            add     r2,r2,r3                  // x + y
   SR:00000394|E0803002            add     r3,r0,r2                  // y=(i + j)+(x+y)
   SR:00000398|E50B3020            str     r3,[r11,#-0x20]       //최종 result 값을 "memory" 에 저장
 
 [% 인자값에 대한 정의]
 
 

 그럼 인라인 어셈블러를 사용하면 얼마나 효율적인지 확인해 보죠.



 j와 x를 더해서 result 변수에 저장하는 프로그램이랍니다.
하나는 함수로 프로그램 했고, 하나는 인라인 명령어로 프로그램을 했는데 얼핏 보면 씨 함수가 더 간단하다고 생각될 수도 있지만 실제 타겟 상에서 프로그램이 실행됐을 때는 많은 성능에 차이가 있답니다.
우선 명령어 코드로 살펴봐요.
 
[씨 언어로 함수를 만들었을 경우]
                   30|int func_sub( int a, int c) {
   SR:000003AC|E1A0C00D__func_sub:_mov_____r12,r13
   SR:000003B0|E92DD800            stmdb   r13!,{r11-r12,r14,pc}
   SR:000003B4|E24CB004            sub     r11,r12,#0x4
   SR:000003B8|E24DD008            sub     r13,r13,#0x8
   SR:000003BC|E50B0010            str     r0,[r11,#-0x10]
   SR:000003C0|E50B1014            str     r1,[r11,#-0x14]
                   31| result = a+c;
   SR:000003C4|E59F101C            ldr     r1,0x3E8
   SR:000003C8|E51B2010            ldr     r2,[r11,#-0x10]
   SR:000003CC|E51B3014            ldr     r3,[r11,#-0x14]
   SR:000003D0|E0823003            add     r3,r2,r3
   SR:000003D4|E5813000            str     r3,[r1]
                   32| return 0;
   SR:000003D8|E3A03000            mov     r3,#0x0
                  33|}
   SR:000003DC|E1A00003            mov     r0,r3
   SR:000003E0|E24BD00C            sub     r13,r11,#0x0C
   SR:000003E4|E89DA800            ldmia   r13,{r11,r13,pc}
   SR:000003E8|30020000             dcd     0x30020000
 
메모리 주소를 살펴보니 000003AC ~ 000003E8까지 명령어가 있네요. 즉, 16byte 만큼 메모리를 사용했어요.
 
 [인라인 어셈블러 명령어로 만들었을 경우]
                   44|    __asm__ __volatile__ (
   SR:00000450|E51B2014            ldr     r2,[r11,#-0x14]
   SR:00000454|E51B3018            ldr     r3,[r11,#-0x18]
   SR:00000458|E0823003            add     r3,r2,r3
   SR:0000045C|E59F2020            ldr     r2,0x484
   SR:00000460|E5823000            str     r3,[r2]
   SR:00000464|E51B3010            ldr     r3,[r11,#-0x10]
   SR:00000468|E2833001            add     r3,r3,#0x1
   SR:0000046C|E50B3010            str     r3,[r11,#-0x10]
   SR:00000470|EAFFFFF3              b       0x444
                      |        "add %0,%1,%2 \n\t"
                      |         :"=r" (result)
                      |         :"r" (j), "r" (x)
                      |         : "memory"
                      |         );
                      |  }
                  51|  return 0;
 
메모리 주소를 살펴보니 00000450 ~ 00000470까지 명령어가 있네요. 즉, 9byte 만큼 메모리를 사용했어요.
 
 두 개의 프로그램 모두 같은 결과이지만 메모리 사용량에서부터 차이가 나며 명령어가 많을 수록 성능은 떨어지게 마련이죠.
 
 
 
 

 

by 히언 | 2010/06/27 22:01 | SOTO Story | 트랙백 | 핑백(1) | 덧글(4)

Linked at 친절한 임베디드 시스템 개발자.. at 2010/06/27 22:03

... sp; 305 씨 언어에서 씨 플러스플러스 함수를 콜하는 방법은? 306 인라인 어셈블러를 사용하려면? 307 소스레벨 디버깅은 어떻게 해야 하나요? &nbsp ... more

Commented by Joy at 2010/06/28 09:13
인라인함수에서 volatile option이 들어가는 걸 이제서야 알았네요..ㅡ.ㅡ;
지금껏 그냥 써왔는데...ㅠ.ㅠ 역시 무식하면 용감한거죠...
잘보고 갑니다. ^^
Commented by soto at 2010/06/28 13:39
도움이 되셨나요?
즐거운 하루 되세용~~!!
Commented by 노란두줄 at 2010/06/29 11:01

항상 잘 보고 있습니다~
다만, 코드 예제가 들어갈 때, indent가 지켜지면 좀 더 가독성이 좋은 글이 될 듯합니다 ^^/
Commented by soto at 2010/06/29 18:59
네..
조금 더 세심하게 정리해서 올리도록 할게요.
좋은 말씀 감사합니다. ^^
※ 이 포스트는 더 이상 덧글을 남길 수 없습니다.

◀ 이전 페이지          다음 페이지 ▶