Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
1
x87 Floating-Point Programming
2
Rejestry koprocesora
3
x87 Data Registers Rejestr danych – osiem 80-bitowych rejestrów fizycznych fpr0 – fpr7 (R0-R7) Dostęp do rejestrów fizycznych – poprzez stos (modulo 8), st0 – st7 (st(0) – st(7)) Wskaźnik TOP – bity rejestru Status Word, adres fizyczny na który wskazuje wierzchołek stosu st0
4
Inicjalizacja FPU TOP = adres fizyczny rejestru R0
FINIT – inicjalizacja FPU FNINIT –bez brania pod uwagę niezałatwionych wyjątków
5
Ładowanie danych z pamięci do rejestru
dekrementujemy wskaźnik TOP TOP = rejestr R7 wstawiamy dane do rejestru R7 dane są konwertowane na Double Extended-Precision Floating-Point
6
Typy danych FPU operuje na 7 typach danych:
Single-Precision Floating-Point Double-Precision Floating-Point Double Extended-Precision Floating-Point Word Integer Doubleword Integer Quadword Integer Packed BCD Integers (binary coded decimal) FPU implementuje IEEE 754 Floating Point Standard.
7
ukryty integer = 1
8
Floating-Point Data Types
Deklarowanie liczb rzeczywistych w NASM dd e20 ; single-precision float (32 bity) dq e20 ; double-precision float (64 bity) dt e20 ; extended-precision float (80 bitów)
9
Reprezentacja liczb Jeśli to możliwe FPU reprezentuje wyniki obliczeń w postaci znormalizowanej. Przykład obliczania wartości: (IEEE 754). Kod binarny dzielimy na poszczególne pola zawierające kolejno znak, cechę oraz bity ułamkowe mantysy: z cecha bity ułamkowe mantysy z = 0 - liczba jest dodatnia c = (BIAS=127) = = 6 m = 01, (U1) = 19/16 Mamy wszystkie niezbędne składniki, wyliczamy wartość liczby: L(IEEE 754) = (-1)zm2c = (-1)0 × 19/16 × 26 = 25/16 × 26= 25 × 22 = 25 × 4 = 100(10) (IEEE 754) = 100(10).
10
Wartości specjalne Wartość zero Not a Number (NaN) znak cecha mantysa
0/1 0…0 0..0 Cichy NaN (QNaN) – przechodzą przez działania arytmetyczne, najczęściej oznaczają wartość niezdefiniowaną Wartość zdenormalizowana znak cecha mantysa 0/1 1…1 1X..X znak cecha mantysa 0/1 0…0 X…1…X Głosny NaN (SNaN) – powodują powstanie wyjątków w obliczneniach Nieskończoność znak cecha mantysa 0/1 1…1 0..0 znak cecha mantysa 0/1 1…1 0X..X Pole znaku określa czy dodatniość/ujemność nieskończoności
11
x87 FPU Status Word Register (FSW)
FSTSW, FNSTSW, FSAVE, FNSAVE, FXSAVE, FSTENV, FNSTENV – kopiują zawartość rejestru do pamięci FRSTOR, FXRSTOR – ładują zawartość pamięci do rejestru FINIT, FNINIT – ustawiają na 0 wszystkie bity rejestru
12
x87 Control Word Register (FCW)
FLDCW, FRSTOR, FXRSTOR – ładują zawartość rejestru z pamięci (można ustawić m.in. precyzje i zaokrąglanie) FSTCW, FNSTCW, FSAVE, FNSAVE, FXSAVE – zapisują zawartość rejestru do pamięci FINIT, FNINIT – ustawiają wartość rejestru na 037Fh, co oznacza: maskowanie wszystkich wyjątków double-extende precyzja round-to-nearest
13
Rounding Control (RC)
14
Precision Control (PC)
Domyślna precyzja: double-extended Instrukcje korzystające z tej wartości: FADD, FADDP, FIADD, FSUB, FSUBP, FISUB, FSUBR, FSUBRP, FISUBR, FMUL, FMULP, FIMUL, FDIV, FDIVP, FIDIV, FDIVR, FDIVRP, FIDIVR, FSQRT
15
x87 Tag Word Register (FTW)
FINIT/FNINIT, FSAVE/FNSAVE - ustawia wartość rejestru na FFFFh FPU używa tego rejestru do wykrycia stack overflow i underflow Programista nie może bezpośrednio ustawiać i modyfikować tego rejestru (FLDENV i FRSTOR)
16
X87 FPU INSTRUCTION Instrukcje przemieszczenia danych
Instrukcje ładowania stałych Działania matematyczne Komendy porównania Instrukcje kontrolne Instrukcje trygonometryczne, logarytmiczne, wykładnicze
17
Instrukcje przemieszczenia danych
Instrukcje przemieszczenia danych mają jeden argument: MNEMONIC st(j) MNEMONIC [mem32/64/80] MNEMONIC [mem16/32/64] Floating Point Integer FLD załaduj liczbę rzeczywistą z pamięci FILD załaduj liczbę całkowitą z pamięci FST do pamięci idzie liczba ze st(0) FIST ewentualnie obciętą do całkowitej liczbę z st(0) zapisz do pamięci FSTP zapisz st(0) w pamięci i zdejmij je ze stosu FISTP ewentualnie obciętą do całkowitej liczbę z st(0) zapisz do pamięci i zdejmij je ze stosu FXCH zamień st(0) z st(i) Instrukcje wstawiania na stos – wskaźnik stosu TOP się dekrementuje, następnie ładujemy dane do rejestru wskazanego przez st0, Instrukcje zdejmowania – ładują dane do pamięci, rejestr st0 zaznaczany jako empty, następnie wskaźnik stosu TOP się inkrementuje
18
Warunkowe przenoszenie danych
FCMOVcc – kopiuje zawartość z rejestru ST(i) do ST(0) w zależności od ustawień EFLAGS Instruction Mnemonic Stan Status Flag Opis warunku FCMOVB CF=1 mniejszy FCMOVNB CF=0 większy FCMOVE ZF=1 równy FCMOVNE ZF=0 nie równy FCMOVBE CF=1 or ZF=1 mniejszy lub równy FCMOVNBE CF=0 or ZF=0 większy lub równy FCMOVU PF=1 Unordered (NaN – Not a Number) FCMOVNU PF=0 not unordered
19
Instrukcje ładowania stałych
FLDZ - ładuje +0.0 FLD1 - ładuje +1.0 FLDPI - ładuje π FLDL2T - ładuje log2 10 FLDL2E - ładuje log2e FLDLG2 - ładuje log102 FLDLN2 - ładuje loge2 Stałe ładowane są do rejestru st0
20
Działania matematyczne
Meomniki instrukcji dodawania, odejmowania, mnożenia i dzielenia przyjmują następujące argumenty: dwa rejestry danych x87 FPU rejestr danych x87 FPU rzeczywistą lub całkowitą liczbę w pamięci MNEMONIC st(0), st(i) MNEMONIC st(i), st(0) MNEMONIC [mem32/64] MNEMONIC [mem16/32int]
21
Dodawanie FADD [mem32/64] st(0) := st(0) + [mem] FADD st(0),st(i)
st(0) := st(0) + st(i) FADD st(i),st(0) st(i) := st(i) + st(0) FADDP st(i), st(0) st(i) := st(i) + st(0) i zdejmij st(0) (inkrementuje TOP) FADDP FADDP st(1), st(0) FIADD [mem16/32int] st0 := st0 + [mem] Uwaga! FADDP używamy jeśli wartość w st(0) nie jest na potrzebna w dalszych obliczeniach. Odejmowania proste działa identycznie, zmieniamy znak + na - FSUB FSUBP FISUB
22
Odejmowanie odwrotne FSUBR [mem32/64] st(0) := [mem] - st(0)
FSUBR st(0),st(i) st(0) := st(i) - st(0) FSUBR st(i),st(0) st(i) := st(0) - st(i) FSUBRP st(i), st(0) st(i) := st(0) - st(i) i zdejmij st(i) FSUBRP FSUBRP st(1), st(0) FISUBR [mem16/32int] st0 := [mem] - st0 Mnożenie – składnia identyczna jak w dodawaniu: FMUL, FMULP, FIMUL Dzielenie – składnia identyczna jak w dodawaniu: FDIV, FDIVP, FIDIV Dzielenie odwrotne – składnia identyczna jak w odejmowaniu odwrotnym: FDIVR, FDIVRP, FIDIVR
23
Pozostałe instrukcje arytmetyczne
FABS wartość bezwzględna st(0) := |st(0)| FCHS zmiana znaku st(0) := -st(0) FSQRT pierwiastek kwadratowy st(0) := SQRT[ st(0) ] FPREM FPREM1 reszta z dzielenia st(0) := st(0) mod st(1) FRNDINT zaokrąglanie do całkowitej st(0) := (int)st(0)
24
Odwrotna notacja polska
- * d post-order (a+b)*c-d a b + c * d - + c a b Uproszczony kod programu: fld [a] fld [b] faddp st1, st0 fld [c] fmulp st1, st0 fld [d] fsubp st1, st0 Teraz st0 jest równe wartości całego wyrażenia.
25
fld [a] fld [b] faddp st1, st0 pop st0 fld [c] fmulp st1, st0 fld [d]
R7 a + b st0 R6 R5 R4 R3 R2 R1 R0 R7 a st0 R6 st7 R5 st6 R4 st5 R3 st4 R2 st3 R1 st2 R0 st1 R7 a st1 R6 b st0 R5 R4 R3 R2 R1 R0 R7 a + b st1 R6 b st0 R5 R4 R3 R2 R1 R0 pop st0 fld [c] fmulp st1, st0 fld [d] fsubp st1, st0 R7 a + b st1 R6 c st0 R5 R4 R3 R2 R1 R0 R7 (a +b) * c st0 R6 R5 R4 R3 R2 R1 R0 R7 (a +b) * c st1 R6 d st0 R5 R4 R3 R2 R1 R0 R7 (a +b) * c -d st0 R6 R5 R4 R3 R2 R1 R0
26
Komendy porównania FCOM st(i)/[mem], FCOMP st(i)/[mem], FCOMPP
porównuje st(0) z st(i) (lub zmienną w pamięci) ustawia flagi kontrolne (C0, C2, and C3) w rejestrze stanu jeśli jedna lub obie wartości są NaN lub mają niezdefiniowany format (unordered condition) generuje wyjątek (floating-point invalid-operation) FICOM [mem] - porównaj st(0) ze zmienną całkowitą 16- lub 32-bitową w pamięci FICOMP [mem] - porównaj st(0) ze zmienną całkowitą 16- lub 32-bitową w pamięci, zdejmij st(0)
27
Branching on the x87 FPU Condition Codes - old mechanism
FSTSW AX – przenosimy rejestr stanu x87 FPU do rejestru AX SAHF – kopiuje rejestr AH do rejestru flag procesora (bity C3, C2 i C0 są kopiowane odpowiednio do flag ZF, PF i CF) Używamy ja, jae, jb, jbe, je, jz … (Unsigned Conditional Jumps) do testowania rezultatów komend porównania koprocesora.
28
Branching on the x87 FPU Condition codes – new mechanism.
FCOMI, FCOMIP st(0), st(i) działają tak samo jak FCOM ustawiają flagi kontrolne (ZF, PF, and CF) w rejestrze EFLAGS procesora możemy od razu używać instrukcji skoku procesora (JZ, JNZ …) FUCOM, FUCOMP, FUCOMPP, FUCOMI, FUCOMIP jeśli unordered condition nie generuje wyjątku
29
Przykład Czy (a+b)*c = a*c + b*c w arytmetyce FPU? a = 1.22e10
b = 2.45e-15 c = 3.45e20
30
section .text gloabl _start _start: FINIT ;inicjalizacja FPU ;(a+b)*c FILD dword [a] FILD dword [b] FADDP st1, st0 FILD dword [c] FMULP st1, st0 ; a*c + b*c FMUL st1, st0 FCOMI st0, st1
31
JE tak ;st1 = st0? MOV ecx, nierowne MOV edx, dlugosc_ nierowne JMP pisz: tak: MOV ecx, rowne MOV edx, dlugosc_ rowne pisz: MOV eax, 4 MOV ebx, 1 INT 80h MOV eax, 1
32
section .data a dd 1.22e10 b dd 2.45e-15 c dd 3.45e20 rowne db ”(a+b)*c = a*c + b*c”, 0ah dlugosc_rowne equ $ - rowne nierowne db ”(a+b)*c != a*c + b*c”, 0ah dlugosc_nierowne equ $ - nierowne
33
Instrukcje kontrolne FCLEX/FNCLEX - wyczyść wyjątki
FLDENV, FSTENV/FNSTENV - wczytaj/zapisz środowisko (rejestry stanu, kontrolny i kilka innych, bez rejestrów danych). Wymaga 14 albo 28 bajtów pamięci, w zależności od trybu pracy procesora (rzeczywisty - DOS lub chroniony - Windows/Linux). FRSTOR, FSAVE/FNSAVE - jak wyżej, tylko że z rejestrami danych. Wymaga 94 lub 108 bajtów w pamięci, zależnie od trybu procesora. FINCSTP, FDECSTP - zwiększ/zmniejsz wskaźnik stosu - przesuń st(0) na st(7), st(1) na st(0) itd. oraz w drugą stronę, odpowiednio. FFREE - zwolnij podany rejestr danych FNOP - no operation. Nic nie robi, ale zabiera czas . WAIT/FWAIT - czekaj, aż FPU skończy pracę. Używane do synchronizacji z CPU.
34
Instrukcje trygonometryczne, logarytmiczne, wykładnicze
Instrukcje trygonometryczne: FSIN, FCOS, FSINCOS, FPTAN, FPATAN st(0) := funkcja[st0]. Logarytmiczne, wykładnicze: FYL2X st1:= st1*log2[st0] i zdejmij st0 FYL2XPI st1 := st1*log2[ st ] i zdejmij F2XM1 st0 := 2^[st0] - 1 FSCALE st0 := 2^[st1]
35
W sieci:
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.