[ Pobierz całość w formacie PDF ]

Jeśli wynik jest mniejszy niż 0, to staje się równy 0.
f& mnożenie:
Ê% PMULHRWC, PMULHRIW, PMULHRWA- mnożenie spakowanych słów,
zaokrąglanie, zapisanie tylko starszych 16 bitów wyniku (z 32).
Ê% PMULHUW - mnożenie spakowanych słów bez znaku, zachowanie starszych 16
bitów
Ê% PMULHW, PMULLW - mnożenie spakowanych słów bez znaku, zapisanie
starszych/młodszych 16 bitów (odpowiednio).
Ê% PMULUDQ - mnożenie spakowanych dwordów bez znaku
f& mnożenie i dodawanie: PMADDWD - do młodszego dworda rejestru docelowego idzie suma
iloczynów 2 najmłodszych słów ze sobą i 2 starszych (bity 16-31) słów ze sobą. Do starszego
dworda - suma iloczynów 2 słów 32-47 i 2 słów 48-63.
" instrukcje porównawcze:
Zostawiają w odpowiednim bajcie/słowie/dwordzie same jedynki (FFh/FFFFh/FFFFFFFFh) gdy
wynik porównania był prawdziwy, same zera - gdy fałszywy.
f& na równość PCMPEQB / PCMPEQW / PCMPEQD (EQ oznacza równość)
f& na większe niż: PCMPGTPB / PCMPGTPW / PCMPGTPD (GT oznacza greater than, czyli
większy)
" instrukcje konwersji:
f& pakowanie: PACKSSWB / PACKSSDW, PACKUSWB - upychają słowa/dwordy do
bajtów/słów i pozostawiają w rejestrze docelowym.
f& rozpakowania starszych części (unpack high): PUNPCKHBW, PUNPCKHWD,
PUNPCKHDQ - pobierają starsze części bajtów/słów/dwordów z jednego i drugiego rejestru,
mieszajÄ… je i zostawiajÄ… w pierwszym.
f& rozpakowania młodszych części (unpack low): PUNPCKLBW, PUNPCKLWD,
PUNPCKLDQ - jak wyżej, tylko pobierane są młodsze części
" instrukcje logiczne:
f& PAND (bitowe AND)
f& PANDN (najpierw bitowe NOT pierwszego rejestru, potem jego bitowe AND z drugim
rejestrem)
f& POR (bitowe OR)
f& PXOR (bitowe XOR)
" instrukcje przesunięcia (analogiczne do znanych SHL, SHR i SAR, odpowiednio):
f& w lewo: PSLLW (słowa) / PSLLD (dword-y), PSLLQ (qword)
f& w prawo, logiczne: PSRLW (słowa) / PSRLD (dword-y), PSRLQ (qword)
f& w prawo, arytmetyczne: PSRAW (słowa)/ PSRAD (dword-y)
" instrukcje stanu MMX:
f& EMMS - Empty MMX State - ustawia rejestry FPU jako wolne, umożliwiając ich użycie. Ta
instrukcja musi być wykonana za każdym razem, gdy kończymy pracę z MMX i chcemy
zacząć pracę z FPU.
66 Bogdan Drozdowski
2007-11-12 Język asembler dla każdego Bogdan Drozdowski
Rzadko która z tych instrukcji traktuje rejestr jako całość, częściej operuje na poszczególnych wartościach
osobno, równolegle.
Spróbuję teraz podać kilka przykładów zastosowania MMX. Ze względu na to, że TASM bez pomocy
zewnętrznych plików z makrami nie obsługuje MMX, będę używał składni NASMa i FASMa.
Przykład 1. Dodawanie dwóch tablic bajtów w pamięci. Bez MMX mogłoby to wyglądać mniej-więcej tak:
(przeskocz dodawanie tablic)
; EDX - adres pierwszej tablicy bajtów
; ESI - adres drugiej tablicy bajtów
; EDI - adres docelowej tablicy bajtów
; ECX - liczba bajtów w tablicach. Przyjmiemy, że różna od zera...
petla:
mov al, [edx] ; pobierz bajt z pierwszej
add al, [esi] ; dodaj bajt z drugiej
mov [edi], al ; zapisz bajt w docelowej
inc edx ; zwiększ o 1 indeksy do tablic
inc esi
inc edi
loop petla ; działaj, dopóki ECX różne od 0.
A z MMX:
(przeskocz dodawanie tablic z MMX)
mov ebx, ecx ; EBX = liczba bajtów
and ebx, 7 ; będziemy brać po 8 bajtów - obliczamy
; więc resztę z dzielenia przez 8
shr ecx, 3 ; dzielimy ECX przez 8
petla:
movq mm0, [edx] ; pobierz 8 bajtów z pierwszej tablicy
paddb mm0, [esi]; dodaj 8 spakowanych bajtów z drugiej
movq [edi], mm0 ; zapisz 8 bajtów w tablicy docelowej
add edx, 8 ; zwiększ indeksy do tablic o 8
add esi, 8
add edi, 8
loop petla ; działaj, dopóki ECX różne od 0.
test ebx, ebx ; czy EBX = 0?
jz koniec ; jeśli tak, to już skończyliśmy
mov ecx, ebx ; ECX = resztka, co najwyżej 7 bajtów.
; te kopiujemy tradycyjnie
petla2:
mov al, [edx] ; pobierz bajt z pierwszej
add al, [esi] ; dodaj bajt z drugiej
mov [edi], al ; zapisz bajt w docelowej
inc edx ; zwiększ o 1 indeksy do tablic
inc esi
inc edi
loop petla2 ; działaj, dopóki ECX różne od 0
koniec:
emms ; wyczyść rejestry MMX, by FPU mogło z nich korzystać
Bogdan Drozdowski 67
Bogdan Drozdowski Język asembler dla każdego 2007-11-12
Podobnie będą przebiegać operacje PAND, POR, PXOR, PANDN.
Przy dużych ilościach danych, sposób drugi będzie wykonywał około 8 razy mniej instrukcji niż pierwszych,
bo dodaje na raz 8 bajtów. I o to właśnie chodziło.
Przykład 2. Kopiowanie pamięci.
Bez MMX:
(przeskocz kopiowanie pamięci)
; DS:SI - zródło
; ES:DI - cel
; ECX - ilość bajtów
mov ebx, ecx ; EBX = ilość bajtów
and ebx, 3 ; EBX = reszta z dzielenia liczby bajtów przez 4
shr ecx, 2 ; ECX = liczba bajtów dzielona przez 4
cld ; kierunek: do przodu
rep movsd ; dword z DS:SI idzie pod ES:DI, DI:=DI+4,
; SI:=SI+4, dopóki CX jest różny od 0
mov ecx, ebx ; ECX = liczba pozostałych bajtów
rep movsb ; resztkÄ™ kopiujemy po bajcie
Z MMX:
(przeskocz kopiowanie pamięci z MMX)
mov ebx, ecx ; EBX = ilość bajtów [ Pobierz całość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • lastella.htw.pl
  •