Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- LAB 5:
- Temat: Jednostka zmiennoprzecinkowa (FPU)
- Wykonane zadania:
- Program 1:
- Szereg Taylora dla arctg(x).
- Program 2:
- -funkcja w ASM sprawdzająca wskazaną flagę (dla określonego wyjątku) w Status Word,
- -funkcja w ASM modyfikująca ustawienia maskowania wyjątków w Control Word (dla wskazanego wyjątku),
- -wykazanie różnicy w działaniu dla maskowania i nie maskowania wyjątków.
- Omówienie działania programu:
- Program 1
- Kod w języku C, do napisania którego została wykorzystana wiedza z poprzednich zajęć.
- extern double taylor(double a, int b);
- int main(void)
- {
- int y;
- double x;
- printf("x od -1 do 1: ");
- scanf("%lf", &x);
- printf("y: ");
- scanf("%d", &y);
- printf("Wynik: %lf\n", taylor(x, y));
- return 0;
- }
- Szereg Taylora dla arctg(x) realizujemy za pomocą:
- WZOR.
- Przyjmowane przez funkcję argumenty, to ilość wyrazów ciągu zapisane w rejestrze rdi oraz kąt
- w rejestrze xmm0.
- Przekazujemy wartości z rejestru xmm0 do rejestrów ST(0), ST(1) i ST(2) przez stos za pomocą instrukcji fldl i fld.
- sub $8, %rsp
- movsd %xmm0, (%rsp)
- fldl (%rsp) # NASZ WPISANY X
- fld %st
- fld %st
- Teraz w ST(0) znajduje się wyraz ciągu, w ST(1) suma ciągu, a w ST(2) znajduje się X.
- Ustawiamy rejestr rsi na zero. Jeżeli wartość w rdi, czyli liczba wyrazów ciągu jest jemu równa, to przechodzimy do końca. Jeżeli nie, to zwiększamy licznik rsi i mnożymy ST(2) razy ST dwa razy, a następnie mnożymy -1.
- movq $0, %rsi
- oblicz:
- cmp %rdi, %rsi
- je dowidzenia
- inc %rsi
- fmul %st(2), %st # RAZY X
- fmul %st(2), %st # JESZCZE RAZ RAZY X
- fmull jeden # RAZY -1
- Do ST(0) umieszczany jest dzielnik, który początkowo ma wartość 1. Dodajemy do niego wartość 2, zapisujemy go i dzielimy wyraz przez ten dzielnik, czyli od ST(1) odejmujemy ST(0). Następnie dzielnik usuwamy, a wyraz ciągu dodajemy do sumy. Wykonujemy znowu pętlę "oblicz" do momentu, kiedy wykonamy pożądaną ilość kroków (wyrazów ciągu).
- fldl dzielnik # ST(0) JEST TERAZ DZIELNIKIEM
- faddl dwa #DODAJEMY 2
- fstpl dzielnik # SCIAGAMY ZE STOSU, ZAPISUJEMY W DZIELNIKU
- fldl dzielnik #ZNOWU WSTAWIAMY DZIELNIK
- fdivr %st, %st(1) # DZIELIMY WYRAZ PRZEZ DZIELNIK
- fstp %st # USUWAMY DZIELNIK
- fadd %st, %st(1) # DODANIE DO SUMY
- jmp oblicz #NASZA PETLA
- Program 2
- W programie C stworzyłam menu, w którym możemy sprawdzić Status Word, zmienić wybraną maskę oraz podzielić przez zero, by sprawdzić poprawność maski. Sprawdzanie flagi w Asemblerze.
- SprawdzFlage:
- movq $0, %rax
- fstsw %ax
- fwait
- ret
- Jeżeli wyjątek jest równy zero, to jest brak wyjątków. Następnie jeżeli reszta z dzielenia jest równa 1, to występuje wyjątek Invalid operation exception, itd. Na przykład.
- wyjatek = wyjatek >> 1;
- if (wyjatek % 2 == 1)
- {
- printf("1. Denormalized operand exception flag\n");
- }
- Następnie zmiana wybranej maski w Asemblerze, wykonana jest za pomocą operacji xor. Zmieniamy wartość wybranego bitu, w zależności od wybranej maski.
- setFlag:
- fstcw controlWord
- fwait
- mov controlWord, %ax
- xor %di, %ax
- nop
- mov %ax, controlWord
- fldcw controlWord
- ret
- Wybieramy maskę za pomocą operacji w C
- int maska = 0;
- maska = pow(2,choice);
- setFlag(maska);
- Test dzielenia przez zero wykonujemy w ten sposób, że do rejestrów ST zapisujemy 0, a następnie 1 za pomocą operacji fldz oraz fld1, a następnie wykonujemy dzielenie. W przypadku, gdy zamaskujemy wyjątek dzielenia przez zero i spróbujemy wykonać dzielenie pojawi nam się komunikat o błędzie.
- Wnioski:
- Wszystkie wykonane zadania działają poprawnie.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement