Programowanie w asemblerze Obliczenia zmiennopozycyjne 17 stycznia 2017
Reprezentacja w Standardzie 754 IEEE Mantysa i wykładnik (cecha) m 2 w W znormalizowanej liczbie mantysa jest liczba stałopozycyjna postaci 1.bbbbbbbbbb..., np. 1.0110001110111 2 7 Dwa standardowe formaty IEEE: single precision (32 bity) i double precision (64 bity) W FPU Intela dodatkowo extended precision (80 bitów).
Klasy liczb: zera ze znakiem znormalizowane nieznormalizowane liczby skończone nieskończoności ze znakiem NaNs (Not a Number : nie liczby) liczby nieokreślone (indefinite)
Zera Znak zera pozwala stwierdzić kierunek powstania underflow pozwala stwierdzić znak nieskończoności, z której wzięto odwrotność przydaje się przy arytmetyce przedziałowej
Normalizacja Brak normalizacji oznacza zmniejszenie dokładności (liczby binarnych cyfr znaczacych). Otrzymanie wyniku nieznormalizowanego oznacza underflow condition (#U). W FPU Intela: floating-point underflow exception = powstanie wyniku nieznormalizowanego floating-point denormal-operand exception = wykrycie, że nieznormalizowana liczba jest argumentem operacji.
Nieskończoności Nieskończoności można porównywać i używać ich w operacjach arytmetycznych.
NaN Rodzaje NaN: m = 1.0xxxxxxx m = 1.1xxxxxxx m = 1.10000000 SNaN (Signaling Nan) jako operand sygnalizuja floating-point invalid-operation exception, trzeba je tworzyć programowo (procesor ich nie generuje) QNaN (Quiet NaN) moga być w zasadzie operandami w operacjach arytmetycznych floating-point indefinite Wykorzystanie: kompilator wypełnia niezainicjowane elementy tablicy NaNami zawierajacymi indeks elementu.
IEEE single precision górny bit (31) to bit znaku s 8 bitów (23..30) na wykładnik w 23 dolne bity (0..22) na mantysę m znormalizowana mantysa ma zawsze postać 1.bbbbbbbbbb..., więc dla oszczędności górnej jedynki nie przechowujemy. cecha przesunięta o 127.
IEEE single precision Przypadki specjalne w = 0 & m = 0: liczba 0 (zależnie od znaku +0 lub -0) w = 0 & m 0: liczba nieznormalizowana w = 255 & m = 0: nieskończoność ( ) w = 255 & m 0: NaN (Not a Number) nieokreślony wynik
IEEE double precision górny bit (63) to bit znaku s 11 bitów (52..62) na wykładnik 52 dolne bity (0..51) na mantysę
Technologie Intela Poczatkowo obliczenia zmiennopozycyjne wykonywano na osobnym koprocesorze zwanym FPU (Floating Point Unit). W kolejnych modelach został on wbudowany w główny procesor. Technologia MMX umożliwia obliczenia równoległe na spakowanych liczbach całkowitych. Pojawiła się w Pentium MMX i Pentium II. Technologia SSE umożliwia obliczenia na spakowanych liczbach zmiennopozycyjnych pojedynczej precyzji. Używa osobnych rejestrów 128-bitowych. Pojawiła się w Pentium III. Technologia SSE2 dodaje spakowane liczby zmiennopozycyjne podwójnej precyzji i spakowane liczby całkowite różnych rozmiarów oraz dodatkowe operacje. W Pentium 4. Technologia SSE3 to tylko dodatkowe operacje. W Pentium 4HT i Xeonie.
FPU Intela Kiedyś był rzeczywiście odrębnym układem (tzw. koprocesor matematyczny), obecnie wbudowany, ale rozdzielenie architektur zostało w postaci osobnego środowiska obliczeniowego Na przykład instrukcje FPU nie moga sięgać do normalnych rejestrów (EAX itp.), bo to inny procesor. Odrębny zestaw rejestrów st0, st1,..., st7, tworzacych stos (st0 na wierzchu). Obliczenia (prawie) zawsze z użyciem wierzchołka stosu. Osobny rejestr stanu ( flagi ), niewidoczny dla normalnego procesora oraz rejestr sterujacy.
Flagi stanu Bity i maski w dwóch miejscach: dla instrukcji FPU x87 FPU status word: bity 0..5 x87 FPU control word: maski 0..5 dla obliczeń SIMD w instrukcjach SSE/SSE2/SSE3 rejestr MXCSR: flagi w bitach 0..5, maski w bitach 7..12. Bity flag (stanu) sa lepkie : pozostaja ustawione aż do ręcznego wyzerowania. Można więc zamaskować wszystkie wyjatki i po wykonaniu całego obliczenia zobaczyć, co się działo
Wyjatki W procesorach Intela jest 6 klas wyjatków z bitami i maskami precomputation Invalid operation (#I), bit IE, maska ME. przepełnienie stosu lub pusty stos (#IS) błędna operacja arytmetyczna (#IA), np. dzielenie przez lub zera przez zero Divide-by-zero (#Z), bit IZ, maska MZ itd. Denormalized operand (#D), brak w standardzie IEEE postcomputation Numeric Overflow (#O) Numeric underflow (#U) Inexact result (precision) (#P), bardzo częste, np. 1/3 Gdy maska ustawiona, to domyślna obsługa wyjatku, wpp. wyjatek zgłaszany
Instrukcje: ładowanie i zapisywanie FLD miejsce Przekłada zawartość miejsca na wierzch stosu. Miejsce może być także rejestrem procesora FPU. FILD miejsce Pobiera liczbę całkowita z pamięci, zamienia na format zmiennopozycyjny i dokłada na stos FLD1 Kładzie jedynkę na wierzchołku stosu FLDZ Kładzie zero na wierzchołku stosu FXCH stn Zamienia miejscami podany rejestr i wierzchołek stosu
Instrukcje: ładowanie i zapisywanie FST miejsce Przekłada zawartość wierzchołka stosu w podane miejsce (może to być także rejestr procesora FPU). FSTP miejsce To samo, ale ze zdjęciem ze stosu. FIST miejsce Zamienia liczbę z wierzchołka stosu na całkowita dwu- lub czterobajtowa i zapisuje w podane miejsce FISTP miejsce To samo, ale ze zdjęciem ze stosu; można dostać liczbę 8-bajtowa.
Instrukcje: arytmetyka FADD miejsce Dodaje zawartość miejsca do wierzchołka stosu (st0). FADD rejestr,st0 Dodaje zawartość wierzchołka stosu (st0) do rejestru. FADDP rejestr,st0 To samo ze zdjęciem ze stosu. FIADD miejsce Dodaje liczbę całkowita z miejsca do wierzchołka stosu (st0).
Przykład [Carter] Przykład sumowania tablicy: SIZE equ 10 section.bss array resq SIZE sum resq 1 lp: section.text mov ecx, SIZE mov esi, array fldz ;inicjujemy st0 fadd qword [esi] ;kolejny element add esi, 8 ;krok loop lp fstp qword sum ;zapisanie wyniku
Instrukcje: arytmetyka Dla odejmowania mamy dwa razy więcej instrukcji, bo to nie jest operacja przemienna, przykłady: FSUB miejsce Odejmuje zawartość miejsca od wierzchołka stosu (st0). FSUBR rejestr,st0 Odejmuje zawartość wierzchołka stosu (st0) od rejestru, wynik do do st0. FSUBR rejestr,st0 To samo, ale wynik do rejestru.
Instrukcje: arytmetyka i porównania Mnożenie i dzielenie analogicznie jak dodawanie i odejmowanie. FCOM miejsce Porównuje miejsce z wierzchołkiem stosu (st0). FCOMP miejsce To samo ze zdjęciem ze stosu. FCOMPP Porównuje st0 z st1 i usuwa oba ze stosu. FTST Porównuje st0 z zerem.
Instrukcje: porównania Instrukcje warunkowe procesora nie uwzględniaja rejestru stanu FPU, dlatego trzeba go najpierw przepisać do EFLAGS. FSTSW miejsce Zapisuje rejestr stanu w podane miejsce, zwykle jest to rejestr AX. Po przerzuceniu do AX instrukcja SAHF można flagi przerzucić do EFLAGS. Jako skoków warunkowych należy używać JA, JB i JZ (inaczej mówiac, liczby zmiennopozycyjne traktujemy jak liczby całkowite bez znaku).
Instrukcje porównania: przykład [Carter] ;;; if (x > y) fld qword [x] fcomp qword [y] fstsw ax sahf jna else_part then_part: ;kod dla then jmp end_if else_part: ;kod dla else end_if: ;przeniesienie rejestru stanu
Instrukcje porównania Od Pentium Pro dwie nowe instrukcje porównania bezpośrednio modyfikujace EFLAGS, ale operujace tylko na rejestrach. COMI rejestr Porównuje rejestr z st0. COMIP rejestr To samo ze zdjęciem ze stosu.
Instrukcje porównania: przykład global dmax %define a1 ebp+8 %define a2 ebp+16 section.text dmax: push ebp mov ebp,esp fld qword [a1] fld qword [a2] fcomi st1 ja a2_mniejszy fxchg st1 a2_mniejszy: pop ebp ret
Instrukcje matematyczne FSQRT Zastępuje wierzchołek stosu (st0) przez jego pierwiastek kwadratowy. FSIN, FCOS, FPTAN To samo dla funkcji sin, cos i tan. Argument w radianach! FPTAN Oblicza tan od wierzchołka stosu (st0) i zastępuje go, a następnie dokłada 1.0 na wierzchołek stosu (pamiatka z czasów, gdy było tylko FPTAN, a nie było FSIN i FCOS). FLDPI, FLDL2E, FLDLN2 Umieszczaja na wierzchołku stosu π, log 2 e, ln 2. Dziwne logarytmy.
Synchronizacja Procesor właściwy ( całkowity ) i jednostka FPU to odrębne środowiska obliczeniowe. Moga pracować równolegle, tzn. podczas wykonywania operacji zmiennopozycyjnej równocześnie wykonuja się (o ile to możliwe) normalne instrukcje. Problem z obsługa wyjatków zmiennopozycyjnych: komórki pamięci, które spowodowały wystapienie wyjatku, mogły już zostać nadpisane przez normalne instrukcje. Stawia to pod znakiem zapytania możliwość analizy sytuacji i naprawy w procedurach obsługi.
Synchronizacja FWAIT Wprowadzono instrukcję FWAIT do umieszczania w kodzie bezpośrednio po instrukcji mogacej powodować wyjatek blokuje ona chwilowo wykonanie dalszych instrukcji. Często ten sam efekt można osiagn ać po prostu zmieniajac kolejność instrukcji, np. ciag fild [count] inc [count] fsqrt zmieniamy na fild [count] fsqrt inc [count]
MMX Rozszerzenie MMX procesorów Pentium daje możliwość równoczesnego wykonywania tych samych operacji na wielu argumentach. Jest to jak gdyby miniaturowy procesor wektorowy. Inna ciekawa cecha MMX jest stosowanie arytmetyki z nasycaniem (saturation) przy przekroczeniu zakresu wynikiem jest największa reprezentowalna wartość (nie ma zawijania ). Taki sposób obliczeń stosuje się czasem w przypadku przetwarzania danych audiowizualnych. Przy korzystaniu z rozszerzenia MMX należy pamietać, że praca w trybie MMX wyklucza operacje zmiennopozycyjne i odwrotnie (bo korzystaja z tych samych rejestrów, tylko różnie je nazywaja), konieczne jest jawne przechodzenie między trybami.