From e74d77ce3bfac548ca18290412b0bd2725a8e7d1 Mon Sep 17 00:00:00 2001 From: Jan Potocki Date: Sat, 1 Jun 2019 14:39:21 +0200 Subject: [PATCH] Wydanie R2019.06.1 --- lab3/Makefile | 10 ++++ lab3/rekurencja-reg.s | 101 ++++++++++++++++++++++++++++++++++++++++ lab3/rekurencja-stack.s | 101 ++++++++++++++++++++++++++++++++++++++++ lab4/Makefile | 7 +++ lab4/asm-printf-scanf.s | 72 ++++++++++++++++++++++++++++ lab4/kwadrat.c | 6 +++ lab5/Makefile | 8 ++++ lab5/arctg.s | 62 ++++++++++++++++++++++++ lab5/arctgc.c | 26 +++++++++++ lab5/fpu.c | 25 ++++++++++ 10 files changed, 418 insertions(+) create mode 100644 lab3/Makefile create mode 100644 lab3/rekurencja-reg.s create mode 100644 lab3/rekurencja-stack.s create mode 100644 lab4/Makefile create mode 100644 lab4/asm-printf-scanf.s create mode 100644 lab4/kwadrat.c create mode 100644 lab5/Makefile create mode 100644 lab5/arctg.s create mode 100644 lab5/arctgc.c create mode 100644 lab5/fpu.c diff --git a/lab3/Makefile b/lab3/Makefile new file mode 100644 index 0000000..8770898 --- /dev/null +++ b/lab3/Makefile @@ -0,0 +1,10 @@ +rekurencja-reg: rekurencja-reg.s + gcc -g rekurencja-reg.s -o rekurencja-reg -no-pie + +rekurencja-stack: rekurencja-stack.s + gcc -g rekurencja-stack.s -o rekurencja-stack -no-pie + +all: rekurencja-reg rekurencja-stack + +clean: + rm -f rekurencja-reg rekurencja-stack diff --git a/lab3/rekurencja-reg.s b/lab3/rekurencja-reg.s new file mode 100644 index 0000000..df07483 --- /dev/null +++ b/lab3/rekurencja-reg.s @@ -0,0 +1,101 @@ +# Jan Potocki 2019 + +# Definicje numerow funkcji systemowych i ich parametrow +SYSEXIT = 60 +SYSREAD = 0 +SYSWRITE = 1 +STDIN = 0 +STDOUT = 1 +STDERR = 2 + +# Stale +number = 5 # Wyraz ciagu (to mozna zmienic, reszty nie ruszac) + +n_size = 8 # Rozmiar bufora + +.bss +num: .space n_size # Bufor + +.text +.globl main + +fun: +# Funkcja obliczajaca wynik ciagu: +# x_0=2 +# x_1=1 +# x_2=3 +# x_i=x_(i-2) - 2*x_(i-3) +# 1 parametr - wyraz ciagu (64-bit int), przekazywany przez rejestr +# Wynik zwracany przez rejestr + +pushq %rbp # Wejscie do funkcji +movq %rsp, %rbp +pushq %rbx # Zachowanie wartosci rejestru rbx, poniewaz bedzie + # pozniej modyfikowany - a wg konwencji wywolan, rbx + # musi byc zachowany po stronie wywolanej funkcji + +cmpq $0, %rdi # rdi - 1. parametr (zgodnie z konwencja wywolan) +je x0 +cmpq $1, %rdi +je x1 +cmpq $2, %rdi +je x2 + +# Rekurencja +# 1 wyraz +subq $2, %rdi # Obliczenie indeksu nowego wyrazu ciagu +pushq %rdi # Zachowanie wartosci rejestru rdi (wg konwencji + # wywolan - po stronie wywolujacego) +call fun # 1. wywolanie rekurencyjne +popq %rdi # Przywrocenie wartosci rejestru rdi +movq %rax, %rbx # Skopiowanie wyniku zwroconego w rejestrze rax + # do rejestru rbx + +# 2 wyraz +subq $1, %rdi # Obliczenie indeksu nowego wyrazu ciagu +pushq %rdi # Zachowanie wartosci rejestru rdi (wg konwencji + # wywolan - po stronie wywolujacego) +call fun # 1. wywolanie rekurencyjne +popq %rdi # Przywrocenie wartosci rejestru rdi +movq $2, %rcx # Mnozenie 2. wyrazu przez 2 +mulq %rcx + +sub %rax, %rbx # Obliczenie roznicy + +# Zwrocenie wyniku obliczen (przez rejestr rax, zgodnie z konwencja) i wyjscie +mov %rbx, %rax +jmp fun_end + +# Zwrocenie wynikow dla poczatkowych wyrazow (przez rejestr rax) +x0: +mov $2, %rax +jmp fun_end + +x1: +mov $1, %rax +jmp fun_end + +x2: +mov $3, %rax + +fun_end: +pop %rbx # Przywrocenie wartosci rejestru rbx +pop %rbp # Wyjscie z funkcji +ret + +main: +movq $number, %rdi # Przekazanie parametru przez rejestr rdi +call fun # Wywolanie funkcji rekurencyjnej +movq %rax, num # Zapisanie w pamieci wyniku zwroconego przez rax + +# Wypisanie wyniku +mov $SYSWRITE, %rax +mov $STDOUT, %rdi +mov $num, %rsi +mov $n_size, %rdx +syscall + +# Koniec programu +mov $SYSEXIT, %rax +mov $0, %rdi +syscall diff --git a/lab3/rekurencja-stack.s b/lab3/rekurencja-stack.s new file mode 100644 index 0000000..0b600d5 --- /dev/null +++ b/lab3/rekurencja-stack.s @@ -0,0 +1,101 @@ +# Jan Potocki 2019 + +# Definicje numerow funkcji systemowych i ich parametrow +SYSEXIT = 60 +SYSREAD = 0 +SYSWRITE = 1 +STDIN = 0 +STDOUT = 1 +STDERR = 2 + +# Stale +number = 5 # Wyraz ciagu (to mozna zmienic, reszty nie ruszac) + +n_size = 8 # Rozmiar bufora + +.bss +num: .space n_size # Bufor + +.text +.globl main + +fun: +# Funkcja obliczajaca wynik ciagu: +# x_0=2 +# x_1=1 +# x_2=3 +# x_i=x_(i-2) - 2*x_(i-3) +# 1 parametr - wyraz ciagu (64-bit int), przekazywany przez stos +# Wynik zwracany przez stos + +pushq %rbp # Wejscie do funkcji +movq %rsp, %rbp +pushq %rbx # Zachowanie wartosci rejestru rbx, poniewaz bedzie + # pozniej modyfikowany - a wg konwencji wywolan, rbx + # musi byc zachowany po stronie wywolanej funkcji + +cmpq $0, 16(%rbp) # 16(%rbp) - 1. parametr przekazany na stosie +je x0 +cmpq $1, 16(%rbp) +je x1 +cmpq $2, 16(%rbp) +je x2 + +# Rekurencja +# 1 wyraz +movq 16(%rbp), %rax # Obliczenie indeksu nowego wyrazu ciagu +subq $2, %rax +pushq %rax # Przekazanie nowego wyrazu przez stos +call fun # 1. wywolanie rekurencyjne +popq %rbx # Zapisanie w rbx wyniku przekazanego przez stos + +# 2 wyraz +movq 16(%rbp), %rax # Obliczenie indeksu nowego wyrazu ciagu +subq $3, %rax +pushq %rax # Przekazanie nowego wyrazu przez stos +call fun # 2. wywolanie rekurencyjne +popq %rax # Zapisanie w rax wyniku przekazanego przez stos +movq $2, %rcx # Mnozenie 2. wyrazu przez 2 +mulq %rcx + +subq %rax, %rbx # Obliczenie roznicy + +# Zwrocenie wyniku obliczen (przez stos) i wyjscie +movq %rbx, 16(%rbp) +jmp fun_end + +# Zwrocenie wynikow dla poczatkowych wyrazow (przez stos) +x0: +movq $2, 16(%rbp) +jmp fun_end + +x1: +movq $1, 16(%rbp) +jmp fun_end + +x2: +movq $3, 16(%rbp) + +fun_end: +popq %rbx # Przywrocenie wartosci rejestru rbx +popq %rbp # Wyjscie z funkcji +ret + +main: +movq $number, %rax # Przekazanie parametru... +pushq %rax # ...przez stos +call fun # Wywolanie funkcji rekurencyjnej +popq %rax # Zapisanie w rax wyniku zwroconego przez stos +movq %rax, num # Zapisanie wyniku w pamieci + +# Wypisanie wyniku +movq $SYSWRITE, %rax +movq $STDOUT, %rdi +movq $num, %rsi +movq $n_size, %rdx +syscall + +# Koniec programu +movq $SYSEXIT, %rax +movq $0, %rdi +syscall diff --git a/lab4/Makefile b/lab4/Makefile new file mode 100644 index 0000000..51fb5e2 --- /dev/null +++ b/lab4/Makefile @@ -0,0 +1,7 @@ +asm-printf-scanf: asm-printf-scanf.s kwadrat.c + gcc -g asm-printf-scanf.s kwadrat.c -o asm-printf-scanf -no-pie + +all: asm-printf-scanf + +clean: + rm -f asm-printf-scanf diff --git a/lab4/asm-printf-scanf.s b/lab4/asm-printf-scanf.s new file mode 100644 index 0000000..377c2f2 --- /dev/null +++ b/lab4/asm-printf-scanf.s @@ -0,0 +1,72 @@ +# Jan Potocki 2019 + +.data +# Definicje numerow funkcji systemowych i ich parametrow +SYSEXIT = 60 +SYSREAD = 0 +SYSWRITE = 1 +STDIN = 0 +STDOUT = 1 +STDERR = 2 + +# Stale +liczba = 130 # Liczba calkowita do wypisania przez printf + +# Ciagi formatujace dla scanf +int1: .asciz "%ld" # 64-bit int +double1: .asciz "%lf" # 64-bit double + +# Ciagi formatujace dla printf +int2: .asciz "%ld\n" # 64-bit int +double2: .asciz "%f\n" # 64-bit double (w printf nie "%lf"!) + +.bss +# Zmienne +x: .space 8 # 64-bit int +y: .space 8 # 64-bit double +wynik: .space 8 # 64-bit double + +.text +.globl main + +main: +pushq %rbp # Wyrownanie stosu (alignment) - wymagane przez + # konwencje wywolan + +# Wczytanie danych +movb $0, %al # Brak parametrow w rejestrach wektorowych +movq $int1, %rdi # Ciag formatujacy +movq $x, %rsi # Wskaznik na x +call scanf + +movb $0, %al # Brak parametrow w rejestrach wektorowych +movq $double1, %rdi # Ciag formatujacy +movq $y, %rsi # Wskaznik na y +call scanf + +# Wywolanie funkcji w C +movq (x), %rdi # Przekazanie x (1. parametr, int) przez wartosc +movq (y), %xmm0 # Przekazanie y (2. parametr, double) przez wartosc +# Liczby rejestrow wektorowych w al nie ustawiamy, bo nasza funkcja przyjmuje +# stala liczbe parametrow (inaczej niz printf czy scanf) +call kwadrat +# Wynik zostanie zwrocony w rejestrze xmm0, ktorym rowniez przekazuje sie go do +# funkcji printf - wiec nic nie trzeba z nim robic + +# Wypisanie wyniku +movb $1, %al # 1 parametr w rejestrze wektorowym (xmm0) +movq $double2, %rdi # Ciag formatujacy +call printf + +# Wypisanie liczby calkowitej ustawionej w stalej +movb $0, %al # Brak parametrow w rejestrach wektorowych +movq $int2, %rdi # Ciag formatujacy +movq $liczba, %rsi # Przekazanie stalej przez wartosc +call printf + +popq %rbp # Przywrocenie stosu do poprzedniego stanu + +# Koniec programu +movq $SYSEXIT, %rax +movq $0, %rdi +syscall diff --git a/lab4/kwadrat.c b/lab4/kwadrat.c new file mode 100644 index 0000000..2d1ce9a --- /dev/null +++ b/lab4/kwadrat.c @@ -0,0 +1,6 @@ +double kwadrat(int x, double y) +{ + double z = x*x + y*y; + + return z; +} diff --git a/lab5/Makefile b/lab5/Makefile new file mode 100644 index 0000000..0f75946 --- /dev/null +++ b/lab5/Makefile @@ -0,0 +1,8 @@ +fpu: fpu.c arctg.s + gcc -g fpu.c arctg.s -o fpu -no-pie -lm + + +all: fpu + +clean: + rm -f fpu diff --git a/lab5/arctg.s b/lab5/arctg.s new file mode 100644 index 0000000..92afe88 --- /dev/null +++ b/lab5/arctg.s @@ -0,0 +1,62 @@ +# Jan Potocki 2019 +# Szereg Taylora arctg(x) dla |x| < 1 +# y = (-1)^n * (x^(2n + 1)) / (2n + 1) + +.globl arctg +.type arctg, @function + +arctg: +pushq %rbp # Wejscie do funkcji +movq %rsp, %rbp +subq $8, %rsp # 64-bit double - tymczasowe miejsce w pamieci na x +subq $4, %rsp # 32-bit int - tymczasowe miejsce w pamieci na 2n+1 + +# Przygotowanie danych +vmovsd %xmm0, -8(%rbp) # Umieszczenie w pamieci argumentu funkcji +movq $0, %r8 # r8 - indeks sumy (n), na razie wyzerowany... +fldz # Umieszczenie 0 na stosie FPU (do sumowania szeregu) + +szereg: +# Glowna petla +incq %r8 # ...trzeba zliczac od 1, indeks jest argumentem ciagu + +# Obliczenie 2n+1 +movq $2, %rax +mulq %r8 +incq %rax +movl %eax, -12(%rbp) # Zapisanie wyniku 2n+1 w pamieci + +# Potegowanie (iteracyjne) +fldl -8(%rbp) # Umieszczenie na stosie FPU poczatkowej wartosci +movq $1, %r9 # r9 - zliczanie wykladnika (zaczynamy od 1. potegi) + +potega: +fmull -8(%rbp) # Mnozenie st(0) przez podstawe potegi (w pamieci) +incq %r9 # Aktualizacja wykladnika +cmpq %r9, %rax # Sprawdzenie czy wykladnik 2n+1 zostal osiagniety +jne potega + +# Dzielenie +fidivl -12(%rbp) + +# Sprawdzenie parzystosci wykladnika w (-1)^n +movq $0, %rdx # rdx - starsza polowka bitow dzielnej +movq %r8, %rax # rax - mlodsza polowka bitow dzielnej +movq $2, %rcx # rcx - dzielnik +divq %rcx +cmpq $1, %rdx # rdx - reszta z dzielenia +jne suma # Reszta 0 -> wykladnik parzysty, jest OK +fchs # Reszta 1 -> wykladnik nieparzysty, potrzebny minus + +suma: +faddp # st(1) - poprzednia iteracja, st(0) - aktualna + +cmpq %r8, %rdi # Sprawdzenie czy wyraz szeregu zostal osiagniety +jne szereg + +fstl -8(%rbp) # Zapisanie wyniku w pamieci... +movsd -8(%rbp), %xmm0 # i zwrocenie w xmm0 (bezposrednio sie nie da) + +addq $12, %rsp # Zwolnienie zmiennych lokalnych +popq %rbp # Wyjscie z funkcji +ret diff --git a/lab5/arctgc.c b/lab5/arctgc.c new file mode 100644 index 0000000..2bdbb18 --- /dev/null +++ b/lab5/arctgc.c @@ -0,0 +1,26 @@ +// Jan Potocki 2019 + +#include + +double arctgc(double x, int kroki) +{ + int wyraz, i; + double potega, wynik; + double suma = 0; + + for(i = 1; i <= kroki; i++) + { + wyraz = 2*i + 1; + potega = pow(x, (double)wyraz); + wynik = potega/(double)wyraz; + + if(i % 2 == 1) + { + wynik = -wynik; + } + + suma += wynik; + } + + return suma; +} diff --git a/lab5/fpu.c b/lab5/fpu.c new file mode 100644 index 0000000..51fed01 --- /dev/null +++ b/lab5/fpu.c @@ -0,0 +1,25 @@ +// Jan Potocki 2019 + +#include +#include +#include "arctgc.c" + +double arctg(double x, int kroki); + +const double x = 0.5; +const int n = 100; + +int main() +{ + double wynik_asm, wynik_c; + + printf("Szereg Taylora arctg(%f) dla n=%d...\n", x, n); + + wynik_asm = arctg(x, n); + wynik_c = arctgc(x, n); + + printf("Wynik asm:\t%f\n", wynik_asm); + printf("Wynik C:\t%f\n", wynik_c); + + return 0; +}