Compare commits
2 Commits
8f4d0e843f
...
2aace2f7bf
| Author | SHA1 | Date | |
|---|---|---|---|
| 2aace2f7bf | |||
| 73648cc0b9 |
@@ -0,0 +1,7 @@
|
||||
all: mul
|
||||
|
||||
mul: mul.s
|
||||
gcc mul.s -o mul
|
||||
|
||||
clean:
|
||||
rm mul
|
||||
@@ -0,0 +1,17 @@
|
||||
Należy napisać program, który:
|
||||
* Ze standardowego strumienia wejściowego odczyta (za pomocą funkcji systemowej _read_) bloki zawierające 512 bajtów każdy. Liczba bloków może być dowolna. Kombinacje bitów w bajtach mogą być dowolne.
|
||||
* Każdy blok potraktowany zostanie jako zapisane po sobie dwie reprezentacje w kodzie naturalnym binarnym. Pierwszy odczytany bajt w bloku zawiera najmniej znaczący bit reprezentacji. Każda z reprezentacji zajmuje ciągłą połowę odczytanego bloku, czyli układ danych w bloku można opisać jako:
|
||||
`A0 A1 A2 ... A255 B0 B1 B2 ... B255`
|
||||
gdzie `Ai` i `Bi` oznaczają kolejne bajty (o indeksach _i_) reprezentacji pierwszej (_A_) i drugiej (_B_).
|
||||
* Po odczytaniu bloku danych, na standardowe wyjście zostanie wypisana reprezentacja iloczynu liczb zapisanych reprezentacjami A i B. Format reprezentacji wyjściowej będzie taki sam, jak wejściowych, ale o odpowiednio dopasowanej wielkości.
|
||||
|
||||
|
||||
Przykładowe dane wejściowe i oczekiwane wyniki są dostępne pod adresem http://zak.iiar.pwr.wroc.pl/materials/architektura/laboratorium%20AK2/Dane/mul.tar.bz2
|
||||
Pliki z rozszerzeniem `.in` to dane wejściowe, pliki `*.out` to oczekiwane odpowiedzi.
|
||||
Docelowo program ma działać dla danych z plików `mul_256.*`, ale dla ułatwienia Państwu pracy na początku realizacji zadania przygotowałem także pliki z reprezentacjami 4-bajtowymi (pliki `mul_4.*`).
|
||||
|
||||
Podczas implementacji największe problemy może Państwu sprawić poprawna realizacja algorytmu mnożenia.
|
||||
Przykładowe koncepcje należy sobie przypomnieć z materiałów z poprzedniego semestru, np. slajdy 38 i 39 pliku http://zak.iiar.pwr.wroc.pl/materials/Arytmetyka%20komputerow/architekura.pdf i podstawy z pliku http://zak.iiar.pwr.wroc.pl/materials/Arytmetyka%20komputerow/mnozenie.pdf
|
||||
Oczywiście zadanie to można zrealizować na wiele sposobów, zmieniając zarówno rozmiar pojedynczych iloczynów częściowych, jak i kolejność ich kumulacji.
|
||||
Można np. kumulację iloczynów częściowych przeprowadzać "wierszami", dodając poszczególne iloczyny częściowe "w poziomie", można także kumulować "kolumnami" sumując iloczyny "w pionie". Można także stosować różne rozwiązania pośrednie.
|
||||
Niezależnie jednak od przyjętego sposobu, koniecznie proszę pamiętać o właściwej propagacji przeniesień.
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
# Jan Potocki 2020
|
||||
|
||||
# Definicje numerow funkcji systemowych i ich parametrow
|
||||
SYSEXIT64 = 60
|
||||
SYSREAD = 0
|
||||
SYSWRITE = 1
|
||||
STDIN = 0
|
||||
STDOUT = 1
|
||||
|
||||
# Stale okreslajace rozmiar przetwarzanych danych
|
||||
num_length = 256
|
||||
# ...tego nie ruszac - inaczej stanie sie "cud nad klawiatura" :-D
|
||||
word_length = 8
|
||||
buf_length = num_length * 2
|
||||
num_words = num_length / word_length
|
||||
buf_words = buf_length / word_length
|
||||
|
||||
.global main
|
||||
|
||||
# Segment niezainicjalizowanych danych
|
||||
.bss
|
||||
|
||||
liczba1: .space num_length
|
||||
liczba2: .space num_length
|
||||
wynik: .space buf_length
|
||||
|
||||
# Segment kodu
|
||||
.text
|
||||
|
||||
main:
|
||||
# Glowna petla
|
||||
petla:
|
||||
mov $SYSREAD, %rax # Wczytanie danych ze standardowego wejscia
|
||||
mov $STDIN, %rdi # ...funkcja systemowa read
|
||||
mov $liczba1, %rsi
|
||||
mov $buf_length, %rdx
|
||||
syscall
|
||||
|
||||
# UWAGA
|
||||
# Tutaj wczytane zostana od razu obie liczby
|
||||
# liczba1 i liczba2 sa w pamieci bezposrednio po sobie...
|
||||
# ...i zostala przekazana do funkcji read dlugosc calego bloku
|
||||
|
||||
cmp $buf_length, %rax # rax - liczba wczytanych bajtow
|
||||
jl koniec # Jezeli nie ma 512, to dane sie skonczyly
|
||||
|
||||
xor %rsi, %rsi # rsi - licznik petli zerujacej
|
||||
|
||||
# Petla zerujaca bufor na wynik
|
||||
wyzeruj:
|
||||
movq $0, wynik(, %rsi, 8)
|
||||
inc %rsi
|
||||
cmp $buf_words, %rsi
|
||||
jl wyzeruj
|
||||
|
||||
xor %rsi, %rsi # rsi - licznik pierwszej petli
|
||||
|
||||
# Mnozenie - petla zewnetrzna
|
||||
petla1:
|
||||
xor %rcx, %rcx # rcx - miejsce na starsza czesc wyniku
|
||||
|
||||
# Flagi przeniesienia (potrzebne sa dwie i tego sie nie uprosci)
|
||||
mov $0, %r8 # r8 - dla koncowego wyniku (w pamieci)
|
||||
clc # RFLAGS - dla biezacego mnozenia (rejestry)
|
||||
pushf # ...oczywiscie z backupem na stosie
|
||||
|
||||
xor %rdi, %rdi # rdi - licznik drugiej petli
|
||||
|
||||
# Mnozenie - petla wewnetrzna
|
||||
petla2:
|
||||
movq liczba1(, %rsi, 8), %rax
|
||||
mulq liczba2(, %rdi, 8)
|
||||
|
||||
mov %rdi, %r9 # r9 - indeks wyniku
|
||||
add %rsi, %r9 # (suma indeksow obu petli)
|
||||
|
||||
# Dodanie starszej czesci wyniku z poprzedniej iteracji
|
||||
popf # Tutaj flagi mamy na stosie...
|
||||
adc %rcx, %rax
|
||||
pushf # ...wiec to jest proste
|
||||
|
||||
# Przygotowanie flagi przeniesienia do sumowania wyniku (patent cz. I)
|
||||
cmp $1, %r8 # Tego nie mamy na stosie...
|
||||
je ustaw_cf1 # ...wiec musimy sprytnym sposobem ;-)
|
||||
|
||||
clc # Przypadek bez przeniesienia
|
||||
jmp dodaj_wynik
|
||||
|
||||
ustaw_cf1:
|
||||
stc # Przypadek z przeniesieniem
|
||||
|
||||
# Dodawanie biezacego wyniku do pamieci
|
||||
# (tam po wszystkich iteracjach bedzie wynik koncowy)
|
||||
dodaj_wynik:
|
||||
adcq %rax, wynik(, %r9, 8)
|
||||
|
||||
# Zapisanie flagi przeniesienia do sumowania wyniku (patent cz. II)
|
||||
jc zapisz_cf
|
||||
|
||||
mov $0, %r8 # Jezeli przeniesienia nie bylo
|
||||
jmp dalej
|
||||
|
||||
zapisz_cf:
|
||||
mov $1, %r8 # Jezeli przeniesienie bylo
|
||||
|
||||
dalej:
|
||||
mov %rdx, %rcx # Przechowanie starszej czesci wyniku w rcx
|
||||
|
||||
inc %rdi
|
||||
cmp $num_words, %rdi
|
||||
jl petla2 # Koniec wewnetrznej petli
|
||||
|
||||
# Tutaj musimy sie jeszcze zajac najstarsza czescia wyniku
|
||||
# (z ostatniej iteracji petli wewnetrznej)
|
||||
inc %r9
|
||||
|
||||
popf # Dodanie przeniesienia z sumowania rejestrow
|
||||
adc $0, %rcx # ...jezeli jakies zostalo
|
||||
|
||||
# Przygotowanie flagi przeniesienia do sumowania wyniku (patent cz. I)
|
||||
cmp $1, %r8
|
||||
je ustaw_cf2
|
||||
|
||||
clc # Przypadek bez przeniesienia
|
||||
jmp dodaj_najstarsze
|
||||
|
||||
ustaw_cf2:
|
||||
stc # Przypadek z przeniesieniem
|
||||
|
||||
dodaj_najstarsze:
|
||||
adcq %rcx, wynik(, %r9, 8)
|
||||
|
||||
inc %rsi
|
||||
cmp $num_words, %rsi
|
||||
jl petla1 # Koniec zewnetrznej petli
|
||||
|
||||
mov $SYSWRITE, %rax # Wypisanie wyniku na standardowe wyjscie
|
||||
mov $STDOUT, %rdi # ...funkcja systemowa write
|
||||
mov $wynik, %rsi
|
||||
mov $buf_length, %rdx
|
||||
syscall
|
||||
|
||||
jmp petla # Koniec glownej petli
|
||||
|
||||
# Wyjscie z programu
|
||||
koniec:
|
||||
mov $SYSEXIT64, %rax # Funkcja systemowa exit...
|
||||
mov $0, %rdi # ...kod zakonczenia - 0
|
||||
syscall
|
||||
Binary file not shown.
Reference in New Issue
Block a user