1. VC++ 6.0

VC++ 6.0 (이하 VC++) 에서는 인라인 어셈블을 __asm 형식으로 사용한다.

여러개의 어셈블 명령어를 사용하려면 { } 로 묶어주면 된다.

2. GCC

GCC 에서는 asm( ); 형식을 사용하거나,
__asm__ ( ); 형식을 사용한다.

보통 __asm__ __volatile__ ( ); 형식으로 사용하라고 권한다.

GCC 는 (명령어 input output) 형태로 들어가게 된다.

자세한 사항은

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html 혹은
http://wiki.kldp.org/wiki.php/DocbookSgml/GCC_Inline_Assembly-KLDP

참고하면 된다.

3. 예제

변수의 overflow 를 체크하는 것을 만들어 보자.

변수가 overflow 가 발생했는지 알아보는 방법은 cpu의 flag 중 CF(carry flag) 가 세팅되어졌는지를 확인하는 것이다.
cpu flag 를 확인하는 방법은 어셈블을 사용할 수 밖에 없다.

flag 를 확인하는 방법 말고 다른 방법또한 존재하겠지만, 인라인 어셈블을 이용해서 확인을 해보도록 하자.
3.1 VC++

__asm {
      pushfd;          // eflags(32bit) 값을 스택에 넣는다.
      pop eax;        // eflags 값을 eax 에 넣는다.
      and eax,0x1;  //  0 bit (CF) 가 1인지 확인을 한다.
      mov i, eax;   // 그 값을 변수 i 에 넣는다.
}

이것을 매크로로 만들어도 된다.

#define CHECKOVERFLOW(x) __asm pushfd __asm pop eax __asm and eax,0x1 __asm mov x,eax

테스트 코드는 다음과 같다.
#include <stdio.h>
#define CHECKOVERFLOW(x) __asm pushfd __asm pop eax __asm and eax,0x1 __asm mov x,eax
int main(int argc, char* argv[])
{
 long l=0xFFFFFFF0;
 int sum;
 int flag;
 scanf("%d",&sum);
 l += sum;
 CHECKOVERFLOW(flag);
 if(flag){
  printf("over flow: %u\n",l);
 }
 else
  printf("not over flow:%u\n",l);
 
 return 0;
}

3.2 GCC

GCC 에서는 VC++ 과 다르게 C 내에서 선언한 변수를 쓸때에는 %0, %1 을 사용하여야 한다.
 asm ("mov %%eax, %0" :"=g"(flag));
여기서 %0 은 flag 란 변수를 뜻하는 말이다.

나머지는 VC++ 과 똑같다.

테스트 코드는 다음과 같다.
  1 #include <stdio.h>
  2
  3 int main()
  4 {
  5   long l=0xFFFFFFF0;
  6   int sum;
  7   int flag=0;
  8
  9   scanf("%d",&sum);
 10   l += sum;
 11
 12   asm ("pushf");
 13   asm ("pop %eax");
 14   asm ("and $0x1, %eax");
 15   asm ("mov %%eax, %0" :"=g"(flag));
 16
 17   if(flag)
 18     printf("overflow : %u\n",l);
 19   else
 20     printf("not overflow : %u\n",l);
 21   return 0;
 22 }



 

+ Recent posts