C 언어 | 고급 기능 | 어셈블리 언어 - __asm

C 언어 코드에 어셈블리 언어를 통합하는 방법을 제공한다. 어셈블리 언어는 컴파일러와 시스템에 의존하기 때문에 이 자리에서는 Microoft Visual C ++ 및 Intel x86 호환 프로세서를 전제로 코드 내에 어셈블리를 통합하는 방법을 설명한다.

C 언어에 어셈블리 언어를 포함하기

C 언어는 인간이 이해하기 쉬운 고급 언어로 분류되지만, 고급 언어 중에서는 매우 기계어에 가까운 존재이기도 한다. 따라서 저급 언어라는 기계어에 가까운 프로그래밍 언어인 어셈블리 언어와의 궁합도 좋다고 생각된다. 어셈블리 언어는 고급 언어와 달리, 기계어로 직접 번역할 수 있는 언어로 하나의 문장이 하나의 기계어로 대응하고 있다.

현대에서는 대부분의 프로그래머가 어셈블리 언어을 사용하지 않게 되었고, 어셈블리 언어를 몰라도 프로그래머가 될 수 있다. 그럼 정말로 어셈블리 언어는 필요없는 언어인 것인까? 그러나 실전의 개발을 하면 의외로 어셈블리 언어의 지식이 필요한 경우가 있다. 예를 들어, 고급 게임 프로그래머가 되기 위해 어셈블리 언어는 빼놓을 수 없다. CPU의 특정 명령 세트(※ 1)를 어셈블리 언어에서 명시적으로 사용함으로써, 연산 속도를 가속화시킬 수 있는 기술이 존재하기 때문이다.

또는 운영 체제의 연구를 할 경우에도 어셈블리 언어의 지식이 필요하다. 현대의 대부분의 운영 체제는 C언어로 작성되어 있지만, 그 기본 부분에는 역시 어셈블리 언어를 사용하지 않으면 안된다.

따라서 C 언어와 어셈블리 언어의 관계는 매우 밀접한 것이 있다. 많은 프로그램은 C 언어를 사용하여 실현할 있지만, 프로그램의 일부로 하드웨어의 기능을 직접 조작하는 것 같은 필요가 있는 경우, 어셈블리 언어를 사용하지 않으면 안된다. 이런 사태에 대비해 일부 컴파일러는 C 언어 소스에서 어셈블리 언어를 작성하는 것이 가능하게 되어 있다. 이를 인라인 어셈블러라고 한다.

인라인 어셈블러는 순수한 어셈블리 언어가 아니라, 일반적으로 C 언어와 어느 정도 협조할 수 있다. 예를 들어, 어셈블리에서 C 언어의 변수와 함수를 호출하는 일이 생길지도 모른다. C 언어의 인라인 어셈블러는 표준이 아닌, 개발 환경에 의존하는 것이므로, 컴파일러는 전혀 어셈블러를 지원하지 않을 수 있다. 물론, 어셈블리 언어는 CPU의 명령 세트에 의존하기 때문에 사용되는 어셈블리 언어 컴파일 환경에 따라 달라진다. C 언어와는 달리, 어셈블리 언어에는 표준이라는 개념이 없다. 따라서 개발 환경이 인라인 어셈블러를 지원하고 있는지, 어떤 명령을 사용할 것인가하는 문제는 이 문서의 범위를 초과한다. 사용하는 개발 환경의 도움말 등을 참조하자.

일반적으로 인라인 어셈블러는 asm 키워드가 사용된다. 이 책을 쓰는 시점에서 가장 유명한 컴파일러 중 하나인 Microsoft Visual C ++에서 __asm 키워드를 사용하여 인라인 어셈블러를 작성할 수 있다.

asm문(Visual C++)

__asm 어셈블러 명령
__asm { 어셈블러 명령 목록 }

__asm 키워드 뒤에는 어셈블리 언어의 명령을 작성할 수 있다. 여러 줄의 명령을 작성하려면 {}를 사용하여 __asm 블록을 작성한다. 한 줄 어셈블러이면 __asm 키워드 직후에 문장을 작성한다.

코드1

#include <stdio.h>

char strInputMessage[] = "2개의 정수를 입력하십시오.>";
char strScanf[] = "%d %d";
char strResult[] = "%d + %d = %d\n";

int main() {
  int x, y;

 __asm {
   push offset strInputMessage
   call dword ptr printf
   add esp, 4
    
    lea eax, [y]
    push eax
    lea ecx, [x]
    push ecx
    push offset strScanf
    call dword ptr scanf
    add esp, 0Ch

    mov eax, x
    mov ebx, y
    add eax, ebx

    push eax
    push y
    push x
    push offset strResult
   call dword ptr printf
   add esp,10h
 }
 return 0;
}

코드1는 __asm 키워드를 사용하여 인라인 어셈블러로 작성된 C 언어 프로그램의 예이다. 이 프로그램은 Microsoft Visual C ++ 6.0에서 컴파일되는 것을 전제로 하고 있다. Microsoft Visual C ++ 인라인 어셈블러는 Intel 486 프로세서의 명령어 세트를 지원하고 있다.

어셈블리 언어의 해설은 특정 컴퓨터에 의존하는데, 이 문서의 범위가 아니므로 생략하지만, 코드1의 인라인 어셈블러는 C 언어의 printf()와 scanf() 함수를 호출한다. 어셈블러에서 C 언어의 변수명 및 함수명이 사용되고 있는 것에 주목한다. 프로그램은 2개의 정수를 x 변수와 y 변수에 입력하고 이들을 더한 결과를 표시하고 종료한다.

이와 같이, C 컴파일러에서 인라인 어셈블러를 지원하는 것이 있기 때문에 연산 속도가 요구되는 프로그램 등에서는 어셈블리 언어를 사용할 수 있다.




최종 수정 : 2017-11-26