x87 Floating-Point Programming

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

Tryby adresowania Prawie każda operacja wykonywana przez mikroprocesor wykonywana jest na pewnych argumentach (lub argumencie). Sposoby wskazywania argumentów.
Katarzyna Szafrańska kl. II ti
Język C/C++ Funkcje.
Wzorce.
UKŁADY ARYTMETYCZNE.
Algorytmy – różne przykłady
Operacje zmiennoprzecinkowe
Wykład 3: Jak działa typowy mikroprocesor?
Mikroprocesory i procesory sygnałowe
Języki programowania C++
Język asemblera Copyright, 2000 © Jerzy R. Nawrocki Wprowadzenie do informatyki.
Sortowanie na stercie Heap Sort
Metody numeryczne Wykład no 1.
CPU.
1 RISC – nasze założenia Podstawowe cechy: Wszystkie operacje są realizowane na rejestrach, Tylko operacje typu load i store wymagają dostępu do pamięci,
Materiały pochodzą z Platformy Edukacyjnej Portalu Wszelkie treści i zasoby edukacyjne publikowane na łamach Portalu
Wykład 7: Zmiennoprzecinkowe mikroprocesory sygnałowe firmy Analog Devices: zastosowania i rodziny architektura podstawowe operacje ALU.
Wykład 2: Liczby rzeczywiste (stało i zmiennoprzecinkowe) Koprocesor
Mapa pamięci mikrokontrolera
Podstawowe składniki funkcjonalne procesora i ich rola.
B. znaki alfabetu D. obrazy
Alokacja pamięci struct Test {char c; int n; double x; } st1; st1 cnxcnx
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Język asemblera i koncepcja von Neumanna
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Podstawy informatyki Wirtotechnologia – Wskaźniki i referencje
Wykład 3: Adresowanie i jednostki obliczeniowe w ADSP 21161N
Wykład 4: Podstawowe operacje ALU, MACC, SHIFTER i DAG
Temat nr 10: System przerwań
Wyrażenia Wyrażenie w Fortranie jest poprawną syntaktycznie kombinacją zmiennych, stałych, operatorów i funkcji. Wyrażenia są jednozdaniowymi przepisami.
Wykład 2: Jak działa typowy mikroprocesor? Budowa procesora rodziny Intel80x86 Architektury CISC i RISC Instrukcje skoków warunkowych Stos Instrukcje operujące.
Zapis informacji Dr Anna Kwiatkowska.
Ułamki zwykłe i liczby mieszane.
Programowanie w języku Fortran 95
Podstawy C# Grupa .NET PO.
Technika Mikroprocesorowa 1
Technika Mikroprocesorowa 1
opracowanie: Agata Idczak
Podstawy informatyki (4)
Budowa procesora rodziny x86
Wyrażenia w Turbo Pascalu.
Jerzy F. Kotowski1 Informatyka I Wykład 11 STRUKTURY I UNIE.
Reprezentacja stało i zmiennopozycjna
Podstawy programowania
Architektura komputerów
Mikroprocesory.
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Budowa programu w asemblerze W ogólnym przypadku linia programu w asemblerze ma następującą budowę: na przykład: tuskocz:adda,r0 ;dodanie do akumulatora.
Przerwanie ang. interrupt.
Architektura systemów komputerowych
Architektura systemów komputerowych jesień 2013
Liczby całkowite dodatnie BCN
„Równania są dla mnie ważniejsze, gdyż polityka jest czymś istotnym tylko dzisiaj, a równania są wieczne.” Albert Einstein.
Stało- i zmiennopozycyjna reprezentacja liczb binarnych
Wykład 7 Synchronizacja procesów i wątków
Stało- i zmiennopozycyjna reprezentacja liczb binarnych
Asembler MCS51. Budowa programu w asemblerze W ogólnym przypadku linia programu w asemblerze ma następującą budowę: na przykład: tuskocz:adda,r0 ;dodanie.
Podstawy arytmetyki komputerowej Paweł Perekietka
WYKŁAD 3 Temat: Arytmetyka binarna 1. Arytmetyka binarna 1.1. Nadmiar
Podstawy Techniki Cyfrowej
Wybrane aspekty programowania w C++ (i nie tylko)
Zasady arytmetyki dwójkowej
Typy liczbowe, zmienne, operatory Zajęcia 4. Zmienne Zmienna – to w programowaniu element programu, który może mieć przypisaną pewną wartość (wartość.
Tryby adresowania i formaty rozkazów mikroprocesora
 Formuła to wyrażenie algebraiczne (wzór) określające jakie operacje ma wykonać program na danych. Może ona zawierać liczby, łańcuchy znaków, funkcje,
Pułapki liczb zmiennoprzecinkowych Adam Sawicki – asawicki.infoasawicki.info
Technika Mikroprocesorowa 1
Format rozkazu Tryby adresowania.
Wykład 3: Adresowanie i jednostki obliczeniowe w ADSP 21161N
Zapis prezentacji:

x87 Floating-Point Programming

Rejestry koprocesora

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 – 13-11 bity rejestru Status Word, adres fizyczny na który wskazuje wierzchołek stosu st0

Inicjalizacja FPU TOP = adres fizyczny rejestru R0 FINIT – inicjalizacja FPU FNINIT –bez brania pod uwagę niezałatwionych wyjątków

Ł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

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.

ukryty integer = 1

Floating-Point Data Types Deklarowanie liczb rzeczywistych w NASM dd 1.234567e20 ; single-precision float (32 bity) dq 1.234567e20 ; double-precision float (64 bity) dt 1.234567e20 ; extended-precision float (80 bitów)

Reprezentacja liczb Jeśli to możliwe FPU reprezentuje wyniki obliczeń w postaci znormalizowanej. Przykład obliczania wartości: 01000010110010000000000000000000(IEEE 754). Kod binarny dzielimy na poszczególne pola zawierające kolejno znak, cechę oraz bity ułamkowe mantysy:   0 10000101 10010000000000000000000 z cecha bity ułamkowe mantysy z = 0 - liczba jest dodatnia c = 10000101(BIAS=127) = 133 - 127 = 6 m = 01,10010000000000000000000(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) 01000010110010000000000000000000(IEEE 754) = 100(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

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

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

Rounding Control (RC)

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

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)

X87 FPU INSTRUCTION Instrukcje przemieszczenia danych Instrukcje ładowania stałych Działania matematyczne Komendy porównania Instrukcje kontrolne Instrukcje trygonometryczne, logarytmiczne, wykładnicze

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

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

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

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]

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

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

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)

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.

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

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)

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.

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

Przykład Czy (a+b)*c = a*c + b*c w arytmetyce FPU? a = 1.22e10 b = 2.45e-15 c = 3.45e20

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

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

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

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.

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[ st0 + 1.0 ] i zdejmij F2XM1       st0 := 2^[st0] - 1 FSCALE st0 := 2^[st1]

W sieci: www.math.uni.wroc.pl/s200154/FPU.pps