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>
__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;
{
long l=0xFFFFFFF0;
int sum;
int flag;
scanf("%d",&sum);
l += sum;
CHECKOVERFLOW(flag);
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 }
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 }