M E N U
Strona główna Assembler -kurs
Assembler -teksty
AntiCracking
API
Opisy narzędzi
Zabezpieczenia CD/DVD
Budowa plików
Sources
Linki
Kontakt

STATYSTYKI

stat4u
PRV.PL - Twoje miejsce w sieci.
Od 06.09.2000
Optymalizacja:
1024x768, IE5
  • Assembler - kurs

  • Instrukcje MMX
  • Po pierwsze, wyjaśnijmy jak działa jednostka MMX. Koliduje ona z jednostką FPU, używając tych samych rejestrów. Programista ma do dyspozycji osiem 64-bitowych rejestrów MMX: MM0..MM7.

    MMX wprowadza także cztery nowe typy danych. Są to: packed bytes, packed words, packed doublewords i quad word. Ponadto jednostka MMX używa technologii nazwanej SIMD (Single Instruction, Multiple Data). Oznacza to, że w wyniku wykonania jednego rozkazu można otrzymać kilka wyników.

    Instrukcje MMX można podzielić na kilka grup:
    - instrukcje transferu danych,
    - instrukcje arytmetyczne,
    - instrukcje porównawcze,
    - instrukcje konwersji,
    - instrukcje logiczne,
    - instrukcje przesunięcia,
    - instrukcje stanu MMX.

    Oznaczenia:
    mm- rejestr jednostki MMX
    m64- 64-bitowa komórka pamięci
    m32- 32-bitowa komórka pamięci
    imm8- 8-bitowa dana

    Instrukcje:
    EMMSCzyści rejestry MMX (i FPU).
    MOVD mm,r/m32Przenosi 32 bity z rejestru MMX do pamięci lub do rejestru FPU.
    MOVQ mm/m64,mm/m64Przenosi 64 bity z rejestru MMX do pamięci lub odwrotnie. Może również przenosić dane z jednego rejestru MMX do innego.
    PACKSSWB mm,mm/m64Packed with Signed Saturation Word to Byte. Rozbiera i przycina 4 słowa z rejestru docelowego do bajtów -128..127 i zapisuje je w czterech najniższych bajtach rejestru docelowego. Następnie rozbiera i przycina 4 słowa z rejestru źródłowego do wartości -128..127 i zapisuje je w czterech najwyższych bajtach rejestru docelowego.
    PACKSSDW mm,mm/m64Packed with Signed Saturation DoubleWord to Word. Rozbiera i przycina 2 podwójne słowa z rejestru docelowego do słów -32678..32677 i zapisuje je w dwóch najniższych słowach rejestru docelowego. Następnie rozbiera i przycina 2 podwójne słowa z rejestru źródłowego do wartości -32768..32767 i zapisuje je w dwóch najwyższych słowach rejestru docelowego.
    PACKUSWB mm,mm/m64Packed with Unsigned Saturation Word to Byte. Rozbiera i przycina 4 słowa z rejestru docelowego do bajtów 0..255 i zapisuje je w czterech najniższych bajtach rejestru docelowego. Następnie rozbiera i przycina 4 słowa z rejestru źródłowego do wartości 0..255 i zapisuje je w czterech najwyższych bajtach rejestru docelowego.
    PACKUSDW mm,mm/m64Packed with Unsigned Saturation DoubleWord to Word. Rozbiera i przycina 2 podwójne słowa z rejestru docelowego do słów 0..65635 i zapisuje je w dwóch najniższych słowach rejestru docelowego. Następnie rozbiera i przycina 2 podwójne słowa z rejestru źródłowego do wartości 0..65635 i zapisuje je w dwóch najwyższych słowach rejestru docelowego.
    PADDB mm,mm/m64Packed Add. Dodaje pierwszy bajt ze źródłowego rejestru do pierwszego bajtu z docelowego rejestru. Wynik jest zawijany (np. 256 staje się 1) i jest przechowywany w pierwszym bajcie docelowego rejestru. To samo dzieje się dla pozostałych 7 bajtów.
    PADDW mm,mm/m64Packed Add. Dodaje pierwsze słowo ze źródłowego rejestru do pierwszego słowa z docelowego rejestru. Wynik jest zawijany i jest przechowywany w pierwszym słowie docelowego rejestru. To samo dzieje się dla pozostałych 3 słów.
    PADDD mm,mm/m64Packed Add. Dodaje pierwsze podwójne słowo ze źródłowego rejestru do pierwszego podwójnego słowa z docelowego rejestru. Wynik jest zawijany i jest przechowywany w pierwszym podwójnym słowie docelowego rejestru. To samo dzieje się dla drugiego podwójnego słowa.
    PADDSB mm,mm/m64Packed Add with Saturation. Dodaje pierwszy bajt ze źródłowego rejestru do pierwszego bajtu docelowego rejestru. Wynik jest przycinany do wartości -128..127 (np. -190 staje się -128) i przechowywany w pierwszym bajcie rejestru docelowego. To samo dzieje się dla pozostałych 7 bajtów.
    PADDSW mm,mm/m64Packed Add with Saturation. Dodaje pierwsze słowo ze źródłowego rejestru do pierwszego słowa docelowego rejestru. Wynik jest przycinany do wartości -32768..32767 i przechowywany w pierwszym słowie rejestru docelowego. To samo dzieje się dla pozostałych 3 słów.
    PADDUSB mm,mm/m64Packed Add with Unsigned Saturation. Dodaje pierwszy bajt ze źródłowego rejestru do pierwszego bajtu docelowego rejestru. Wynik jest przycinany do wartości 0..255 (np. 300 staje się 255) i przechowywany w pierwszym bajcie rejestru docelowego. To samo dzieje się dla pozostałych 7 bajtów.
    PADDUSW mm,mm/m64Packed Add with Unsigned Saturation. Dodaje pierwsze słowo ze źródłowego rejestru do pierwszego słowa docelowego rejestru. Wynik jest przycinany do wartości 0..65635 i przechowywany w pierwszym słowie rejestru docelowego. To samo dzieje się dla pozostałych 3 słów.
    PAND mm,mm/m64Logical AND. Wykonuje operację logiczną AND. Wynik jest przechowywany w rejestrze docelowym.
    PANDN mm,mm/m64Logical AND-NOT. Wykonuje operację logiczną AND-NOT. Wynik jest przechowywany w rejestrze docelowym.
    PCMPEQB mm,mm/m64Packed Compare for Eqal. Porównuje pierwszy bajt z rejestru źródłowego z pierwszym bajtem rejestru docelowego. Jeśli są równe pierwszy bajt rejestru docelowego jest równy 11111111b, a jeśli nie to 00000000b. To samo dzieje się dla pozostałych 7 bajtów.
    PCMPEQW mm,mm/m64Packed Compare for Eqal. Porównuje pierwsze słowo z rejestru źródłowego z pierwszym słowem rejestru docelowego. Jeśli są równe pierwsze słowo rejestru docelowego w zapisie bitowym ma same 1, a jeśli nie to same 0. To samo dzieje się dla pozostałych 3 słów.
    PCMPEQD mm,mm/m64Packed Compare for Eqal. Porównuje pierwsze podwójne słowo z rejestru źródłowego z pierwszym podwójnym słowem rejestru docelowego. Jeśli są równe pierwsze podwójne słowo rejestru docelowego w zapisie bitowym ma same 1, a jeśli nie to same 0. To samo dzieje się dla drugiego podwójnego słowa.
    PCMPGTB mm,mm/m64Packed Compare Greater Than. Porównuje pierwszy bajt z rejestru źródłowego z pierwszym bajtem rejestru docelowego. Jeśli pierwszy jest większy pierwszy bajt rejestru docelowego jest równy 11111111b, a jeśli nie to 00000000b. To samo dzieje się dla pozostałych 7 bajtów.
    PCMPGTW mm,mm/m64Packed Compare Greater Than. Porównuje pierwsze słowo z rejestru źródłowego z pierwszym słowem rejestru docelowego. Jeśli pierwsze jest większe pierwsze słowo rejestru docelowego w zapisie bitowym ma same 1, a jeśli nie to same 0. To samo dzieje się dla pozostałych 3 słów.
    PCMPGTD mm,mm/m64Packed Compare Greater Than. Porównuje pierwsze podwójne słowo z rejestru źródłowego z pierwszym podwójnym słowem rejestru docelowego. Jeśli pierwsze jest większe pierwsze podwójne słowo rejestru docelowego w zapisie bitowym ma same 1, a jeśli nie to same 0. To samo dzieje się dla drugiego podwójnego słowa.
    PMADDWD mm,mm/m64Packed Multiply and Add. Mnoży pierwsze słowo z rejestru źródłowego przez pierwsze słowo rejestru docelowego. To samo dzieje się dla pozostałych 3 słów. Wynikiem mnożenia jest podwójne słowo. Pierwszy wynik jest dodawany do drugiego i przechowywany w pierwszym podwójnym docelowego rejestru. Drugi wynik jest sumowany z trzecim i przechowywany w drugim podwójnym słowie docelowego rejestru.
    PMULHW mm,mm/m64Packed Multiply High. Mnoży słowa z źródłowego rejestru przez słowa rejestru docelowego. W rejestrze docelowym przechowywany są wyższe słowa z wyników tego mnożenia.
    PMULLW mm,mm/m64Packed Multiply Low. Mnoży słowa z źródłowego rejestru przez słowa rejestru docelowego. W rejestrze docelowym przechowywany są niższe słowa z wyników tego mnożenia.
    POR mm,mm/m64Logical OR. Wykonuje operację logiczną OR. Wynik jest przechowywany w rejestrze docelowym.
    PSLLW mm,mm/m64/imm8Packed Shift Left Logical. Powoduje przesunięcie bitów w lewo w każdym słowie rejestru docelowego o liczbę określoną w słowach rejestru źródłowego.
    PSLLD mm,mm/m64/imm8Packed Shift Left Logical. Powoduje przesunięcie bitów w lewo w każdym podwójnym słowie rejestru docelowego o liczbę określoną w podwójnych słowach rejestru źródłowego.
    PSLLQ mm,mm/m64/imm8Packed Shift Left Logical. Powoduje przesunięcie bitów w lewo w rejestrze docelowym o liczbę określoną w rejestrze źródłowym.
    PSRLW mm,mm/m64/imm8Packed Shift Right Logical. Powoduje przesunięcie bitów w prawo w każdym słowie rejestru docelowego o liczbę określoną w słowach rejestru źródłowego.
    PSRLD mm,mm/m64/imm8Packed Shift Right Logical. Powoduje przesunięcie bitów w prawo w każdym podwójnym słowie rejestru docelowego o liczbę określoną w podwójnych słowach rejestru źródłowego.
    PSRLQ mm,mm/m64/imm8Packed Shift Right Logical. Powoduje przesunięcie bitów w prawo w rejestrze docelowym o liczbę określoną w rejestrze źródłowym.
    PSRAW mm,mm/m64/imm8Packed Shift Right Arythmetic. Działa tak jak PSRLW, lecz uwzględnia znaki słów.
    PSRAD mm,mm/m64/imm8Packed Shift Right Arythmetic. Działa tak jak PSRLD, lecz uwzględnia znaki podwójnych słów.
    PSUBB mm,mm/m64Packed Subtraction. Odejmuje od każdego z 8 bajtów rejestru docelowego 8 bajtów rejestru źródłowego. Wynik zapisuje w rejestrze docelowym.
    PSUBW mm,mm/m64Packed Subtraction. Odejmuje od każdego z 4 słów rejestru docelowego 4 słowa rejestru źródłowego. Wynik zapisuje w rejestrze docelowym.
    PSUBD mm,mm/m64Packed Subtraction. Odejmuje od każdego z 2 podwójnych słów rejestru docelowego 2 podwójne słowa rejestru źródłowego. Wynik zapisuje w rejestrze docelowym.
    PSUBSB mm,mm/m64Packed Subtraction with Signed Saturation. Odejmuje od każdego z 8 bajtów ze znakiem rejestru docelowego 8 bajtów rejestru źródłowego. Wynik zapisuje w rejestrze docelowym i przycina do wartości -128..127.
    PSUBSW mm,mm/m64Packed Subtraction with Signed Saturation. Odejmuje od każdego z 4 słów ze znakiem rejestru docelowego 4 słowa rejestru źródłowego. Wynik zapisuje w rejestrze docelowym i przycina do wartości -32768..32767.
    PSUBUSB mm,mm/m64Packed Subtraction with Unsigned Saturation. Odejmuje od każdego z 8 bajtów bez znaku rejestru docelowego 8 bajtów rejestru źródłowego. Wynik zapisuje w rejestrze docelowym i przycina do wartości 0..255.
    PSUBUSW mm,mm/m64Packed Subtraction with Unsigned Saturation. Odejmuje od każdego z 4 słów bez znaku rejestru docelowego 4 słowa rejestru źródłowego. Wynik zapisuje w rejestrze docelowym i przycina do wartości 0..65635.
    PUNPCKHBW mm,mm/m64Unpack High. Instrukcja bierze 5 bajt z rejestru docelowego i przechowuje go w 1 bajcie rejestru docelowego. 6 bajt rejestru docelowego jest stawiany na 3 pozycji w tym rejestrze. 7 bajt rejestru docelowego przechowywany jest na 5 pozycji rejestru docelowego. 6 bajt rejestru źródłowego jest stawiany na pozycję 4 rejestru docelowego. 8 bajt rejestru docelowego jest stawiany na 7 pozycji tego samego rejestru. 7 bajt rejestru źródłowego jest stawiany na 6 pozycji rejestru docelowego. 8 bajt z rejestru źródłowego jest stawiany na 8 pozycję w rejestrze docelowym. Na końcu najwyższe bajty z obu rejestrów są ułożone naprzemian w rejestrze docelowym.
    PUNPCKHWD mm,mm/m64Unpack High. Podobna do PUNPCKHBW tyle, że układa najwyższe słowa.
    PUNPCKHDQ mm,mm/m64Unpack High. Podobna do PUNPCKHBW tyle, że układa najwyższe podwójne słowa.
    PUNPCKLBW mm,mm/m64Unpack Low. Instrukcja bierze 4 bajt z rejestru źródłowego i przechowuje go w 8 bajcie rejestru docelowego. 4 bajt rejestru docelowego jest stawiany na 7 pozycji w tym rejestrze. 3 bajt rejestru źródłowego jest stawiany na 6 pozycji rejestru docelowego. 3 bajt rejestru docelowego przechowywany jest na 5 pozycji rejestru docelowego. 2 bajt rejestru źródłowego jest stawiany na pozycję 4 rejestru docelowego. 2 bajt rejestru docelowego jest stawiany na 3 pozycji tego samego rejestru. 1 bajt rejestru źródłowego jest stawiany na 2 pozycji rejestru docelowego. Na końcu najniższe bajty z obu rejestrów są ułożone naprzemian w rejestrze docelowym.
    PUNPCKLWD mm,mm/m64Unpack Low. Podobna do PUNPCKLBW tyle, że układa najniższe słowa.
    PUNPCKLDQ mm,mm/m64Unpack Low. Podobna do PUNPCKLBW tyle, że układa Najniższe podwójne słowa.
    PXOR mm,mm/m64Logical XOR. Wykonuje operację logiczną XOR. Wynik jest przechowywany w rejestrze docelowym.


    Oto przykład użycia instrukcji MMX do rotacji 2D:

    X'=COS(ALPHA)*X+SIN(ALPHA)*Y
    Y'=COS(ALPHA)*Y-SIN(ALPHA)*X

    Segment danych powinien wyglądać tak:

    COS_ALPHA1dw 00h
    SIN_ALPHA1dw 00h
    COS_ALPHA2dw 00h
    SIN_ALPHA2dw 00h
    X1dw 00h
    Y1dw 00h
    Y2dw 00h
    X2dw 00h
    Xor Eax,Eax
    Xor Ebx,Ebx
    Mov Bx,[ALPHA]
    Shl Ebx,1
    Mov Edi,offset SINCOSTAB
    Mov Ax,[Edi+Ebx+(64*2)]
    Mov [COS_ALPHA1],Ax
    Mov [COS_ALPHA2],Ax
    Mov Ax,[Edi+Ebx]
    Mov [SIN_ALPHA1],Ax
    Neg Ax
    Mov [SIN_ALPHA2],Ax
    Mov Ax,[X_TO_ROTATE]
    Mov [X1],Ax
    Mov [X2],Ax
    Mov Ax,[Y_TO_ROTATE]
    Mov [Y1],Ax
    Mov [Y2],Ax
    MovQ mm0,QWord PTR [COS_ALPHA1]
    PMAddWD mm0,QWord PTR [X1]
    PSRAD mm0,8
    MovD Eax,mm0
    PSRLQ mm0,32
    MovD Ebx,mm0

    W Eax mamy X', a Ebx Y'.

    ©Copyright by Konrad Łukasik

    <<

    ©Copyright by zoomek 2001
    Wszelkie prawa zastrzeżone!