Wydanie R2019.06.1
This commit is contained in:
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
double kwadrat(int x, double y)
|
||||||
|
{
|
||||||
|
double z = x*x + y*y;
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// Jan Potocki 2019
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
// Jan Potocki 2019
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user