· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
PentiumMMX



Pentium의 MMX의 사용



1.1. MMX란?

  • MMX는 MultiMedia eXtension의 약자로 그 목적은 범용레지스터의 크기보다 큰 정수연산을 보다 빠르게 하기 위함입니다.
  • 이 문서를 작성하는 현재시점을 기준으로 MM0 ~ 7까지의 특수 명칭이 MMX에 사용되고 있으며 이름만 이렇게 사용될뿐 사실상 부동소수점 연산용 레지스터를 사용하게 됩니다. (이러한 이유로 아래 설명하지만 EMMS의 명령에 대해서 필요한 이유를 이해하세요!)
  • MMX의 가장 대표적인 기능으로는 8바이트 단위로 Data를 전송하는 것인데 이것 말고도 기본 산술연산 및 논리연산을 할수 있게 되어 있습니다.
  • MMX는 범용레지스터로 하는 기능과 비교했을 때 다른 점이 Packed mode라는 것이 있는데 아직 이것에 대한 필요성을 제가 못느끼고 있는 관계로 나중에 필요성이 생기면 정리좀 해보겠습니다.

1.2. MMX의 지원여부 판단

  • 아래와 같이 cpuid명령을 통하여 해당 기능의 지원 여부를 확인 할수 있습니다. 이밖에 3D-NOW같은 경우도 비슷한 방법으로 지원여부를 알수 있겠습니다.

int MZ_IsMMX(void)
{
 static int s_Return = (-1);^I
 if(s_Return == (-1))
 {
  __asm__ __volatile__(
   "\n\t"
   "movl $1, %%eax\n\t"
   "cpuid\n\t"
   "xorl %%eax, %%eax\n\t"
   "testl $0x800000, %%edx\n\t"
   "jz L_Return\n\t"
   "incl %%eax\n\t"
   "L_Return:\n\t"
   "movl %%eax, %0\n\t"
   "\n\t"
   : "=m"(s_Return)
   :
   : "ebx"
  );
 }
 return(s_Return);
}


1.3. MMX 명령어 요약표

  • 특별한 설명이 없더라도 아래의 요약표를 보시면 어셈블리 개발자분들이라면 그리 어렵지 않게 접근하실수 있을겁니다.
  • EMMS에 대해 간단히 추가설명하자면 부동소수점 연산을 하기 위해서 상태를 지울 필요가 있는데 그런 경우에 적절히 삽입하여 사용하여야 합니다. (즉, MMX명령을 사용하게 되면 EMMS명령은 뒤따라야 골치아픈 오동작 계산을 방지할수 있습니다.)

기능 값의 순환이 고려될 때 부호가 고려될 때 부호가 고려되지 않을 때
산술덧셈 PADDB, PADDW, PADDD PADDSB, PADDSW PADDUB, PADDUW
산술뺄셈 PSUBB, PSUBW, PSUBD PSUBSB, PSUBSW PSUBUB, PSUBUW
산술곱셈 PMULL, PMULH
산술곱셈자리올림 PMADD
비교 PCMPEQB, PCMPEQW, PCMPEQD
PCMPGTPB, PCMPGTPW, PCMPGTPD
변환 PUNPCKHBW PACKSSWB PACKUSWB
PUNPCKHWD PACKSSDW
PUNPCKHDQ
PUNPCKLBW
PUNPCKLWD
PUNPCKLDQ
논리연산 묶음의 단위 Quad단위
PAND
PANDN
POR
PXOR
PSLLQ
PSRLQ
전송 Double word 전송 Quad word 전송
MOVD MOVQ
MMX 상태를 비움 EMMS

1.4. 프로그램에 적용해보기


1.4.1. Inline assembly에 어떻게 적용할 것인가?

  • Clobber에 어떻게 두어야 사용할수 있을까요? 아래의 간단한 예제를 보시다시피 "X"라는 것이 현재로서는 적당한듯 싶군요. 필자는 사실상 이렇게 쓰는것이 별로 마음에 내키지 못하여 그냥 *.s 로 Inline이 아닌 상태로 대부분 사용하기는 하지만 가끔은 Inline을 아래와 같이 사용하기는 합니다. 혹시 더 적당한 Clobber를 알고 계시다면 주저없이 알려주시면 좋겠군요.
  • "X"는 어떠한 인자라도 허용하는 것이라는 점을 노파심에 설명 드리며 사실상 왠만한거는 모르겠다 싶으면 이것을 쓰면 잘 되죠. (안되면 골치아픈거 아시죠?)

unsigned long long MZ_NopMMX(unsigned long long s_Value)
{
 unsigned long long s_Return;
 __asm__ volatile(
  "\n\t"
  "movd %1, %%mm0\n\t"
  "movd %%mm0, %0\n\t"
  "emms\n\t"
  "\n\t"
  : "=X"(s_Return)
  : "X"(s_Value)
 );
 return(s_Return);
}


1.5. 문서를 마치며

  • 이 문서를 작성하기 위해 Intel pentium manual을 참조하였습니다. 자세한것은 Intel의 홈페이지를 방문하세요.
  • 본 문서의 최근 버젼은 [http]http://minzkn.pe.ky에서 보실수 있습니다.




sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2004-12-04 20:44:28
Processing time 0.0294 sec