Skip to content

Instantly share code, notes, and snippets.

@do-berry
Created April 26, 2019 09:39
Show Gist options
  • Select an option

  • Save do-berry/ff6573e83e26a4632dc687815a1eccfd to your computer and use it in GitHub Desktop.

Select an option

Save do-berry/ff6573e83e26a4632dc687815a1eccfd to your computer and use it in GitHub Desktop.
zapis do pliku
.data
STDIN = 0
STDOUT = 1
SYSREAD = 0
SYSWRITE = 1
SYSOPEN = 2
SYSCLOSE = 3
FREAD = 0
FWRITE = 1
SYSEXIT = 60
EXIT_SUCCESS = 0
file_in: .ascii "in.txt\0" # Plik z którego odczytany zostanie ciąg wejściowy
file_out: .ascii "out.txt\0" # Plik do którego zostanie zapisany wynik
.bss
.comm in, 1024 # Bufor zawierający znaki (cyfry hex) odczytane z pliku
.comm value, 528 # Bufor zawierający wartości kolejnych bajtów odczytanej
# liczby. Jego rozmiar jest spowodowany konwersji systemów
# korzystając z właściwości baz skojarzonych. Wspólną
# wielokrotnością 4 (ilość bitów które koduje jedna
# cyfra heksadecymalna) i 3 (-||- w systemie ósemkowym).
.comm out, 1409 # Bufor wyjściowy zawierający znaki ósemkowe po konwersji.
# Rozmiar jest większy o jeden z uwagi na znak końca linii.
.text
.globl main # Dla debugowania
main:
# WYZEROWANIE BUFORA WARTOŚCI
mov $528, %r8 # Licznik dla pętli zerującej
mov $0, %al # Wartość wstawiana do bufora
petla1:
dec %r8
mov %al, value(, %r8, 1) # Zapisywanie wartości 0 (z AL) do bufora
cmp $0, %r8 # Powrót do petla1 jeśli licznik > 0
jg petla1
# WCZYTANIE PIERWSZEGO CIĄGU
# Otwarcie pliku $file_in do odczytu
mov $SYSOPEN, %rax
mov $file_in, %rdi
mov $FREAD, %rsi
mov $0, %rdx
syscall
mov %rax, %r10 # Przepisanie identyfikatora otwartego pliku do R10
# Odczyt z pliku do bufora
mov $SYSREAD, %rax
#mov $STDIN, %rdi
mov %r10, %rdi
mov $in, %rsi
mov $1024, %rdx
syscall
mov %rax, %r8 # Zapisanie ilości odczytanych bajtów do rejestru R8
# Zamknięcie pliku
mov $SYSCLOSE, %rax
mov %r10, %rdi
mov $0, %rsi
mov $0, %rdx
syscall
# DEKODOWANIE JEGO WARTOŚCI W PĘTLI
dec %r8 # Pomijamy znak końca linii
mov $528, %r9 # Licznik do pętli. Liczymy od końca, aby dekodowane
# wartości dopisywać od na koniec bufora.
petla2:
dec %r8
dec %r9
# DEKODOWANIE PIERWSZYCH 4 BITÓW
mov in(, %r8, 1), %al
# Wybór odpowiedniej sytuacji poniżej
cmp $'A', %al
jge litera
# Jeśli cyfra < A
sub $'0', %al
jmp powrot_do_petli2_1
# Jeśli cyfra >= A
litera:
sub $55, %al
# Powrót do pętli po odjęciu kodu '0' lub 'A'
# aby uzyskać wartość cyfry z jej kodu ASCII.
powrot_do_petli2_1:
# Wyskok z pętli jeśli zdekodowano ostatnią cyfrę z bufora in
cmp $0, %r8
jle powrot_do_petli2_3
# DEKODOWANIE KOLEJNYCH 4 BITÓW
mov %al, %bl
dec %r8
mov in(, %r8, 1), %al
cmp $'A', %al
jge litera2
sub $'0', %al
jmp powrot_do_petli2_2
litera2:
sub $55, %al
powrot_do_petli2_2:
# Pomnożenie wartości zdekodowanej cyfry przez 16 (drugiej części
# bajtu) i dodanie jej do obecnej liczby w buforze.
mov $16, %cl
mul %cl
add %bl, %al
# Zapisanie zdekodowanego bajtu do nowego bufora
powrot_do_petli2_3:
mov %al, value(, %r9, 1)
# Powrót na początek pętli, aż do zdekodowania całego ciągu
cmp $0, %r8
jg petla2
# KONWERSJA NA SYSTEM ÓSEMKOWY I ZAPIS DO ASCII
mov $527, %r8 # Licznik bajtów z bufora value
mov $1407, %r9 # Licznik znaków ósemkowych z bufora out
petla3:
# Odczyt kolejnych bajtów i przesunięcia bitowe,
# aby pobrać z bufora value, do rejestru RAX
# 3 kolejne bajty we właściwej kolejności.
mov $0, %rax
sub $2, %r8
mov value(, %r8, 1), %al
shl $8, %rax
inc %r8
mov value(, %r8, 1), %al
shl $8, %rax
inc %r8
mov value(, %r8, 1), %al
sub $3, %r8
mov $8, %r10 # Licznik dla zagnieżdżonej pętli w której nastąpi
# odczyt 8 znaków ósemkowych z 3 bajtowej liczby.
petla4:
mov %al, %bl # Skopiowanie pierwszego bajtu liczby do rejestru BL
and $7, %bl # Usunięcie wszystkich bitów poza trzema najmniej znaczącymi
add $'0', %bl # Dodanie kodu znaku ASCII '0' do wyniku maskowania
mov %bl, out(, %r9, 1) # Zapis znaku ASCII do bufora wyjściowego
shr $3, %rax # Przesunięcie bitowe dotychczasowej liczby o 3 bity w prawo,
# tak aby pozbyć się już zdekodowanych 3 bitów.
dec %r9 # Zmniejszenie liczników pętli
dec %r10
cmp $0, %r10 # Skok na początek zagnieżdżonej pętli,
# jeśli pozostały jeszcze bity liczby do zdekodowania
jg petla4
cmp $0, %r8 # Skok na początek petla3, aby pobrać kolejne
jg petla3 # 3 bajty cyfry do dekodowania.
# ZAPISANIE WYNIKU
# Otwarcie pliku $file_out do zapisu.
# Jeśli plik nie istnieje, utworzenie go z prawami 644.
mov $SYSOPEN, %rax
mov $file_out, %rdi
mov $FWRITE, %rsi
mov $0644, %rdx
syscall
mov %rax, %r8
# Zapis bufora out do pliku
movq $1408, %r9
movb $0x0A, out(, %r9, 1)
mov $SYSWRITE, %rax
#mov $STDOUT, %rdi
mov %r8, %rdi
mov $out, %rsi
mov $1409, %rdx
syscall
# Zamknięcie pliku
mov $SYSCLOSE, %rax
mov %r8, %rdi
mov $0, %rsi
mov $0, %rdx
syscall
# ZWROT WARTOŚCI EXIT_SUCCESS
mov $SYSEXIT, %rax
mov $EXIT_SUCCESS, %rdi
syscall
.data
SYSREAD = 0
SYSWRITE = 1
SYSOPEN = 2
SYSCLOSE = 3
FREAD = 0
FWRITE = 1
file_out: .ascii "out.txt\0" # Nazwa pliku musi kończyć się zerowym bajtem
.bss
.comm out_buffer, 1024
# Otwarcie pliku $file_out do zapisu
# Jeśli plik nie istnieje, zostanie on utworzony z prawami dostępu 644:
# 6 - zapis (2) i odczyt (4) przez właściciela - użytkownika tworzącego plik
# 4 - odczyt przez grupę do której należy właściciel i został przypisany plik
# (Właściciel może znajdować się w wielu grupach, ale plik musi przynależeć
# do dokładnie jednej z nich. Domyślnie jest to grupa zawierająca jedynie
# właściciela.)
# 4 (kolejne) - odczyt przez wszystkich pozostałych użytkowników
mov $SYSOPEN, %rax # Pierwszy parametr - numer wywołania systemowego
mov $file_out, %rdi # Drugi parametr - nazwa pliku
mov $FWRITE, %rsi # Trzeci parametr - sposób otwarcia
mov $0644, %rdx # Czwarty parametr - prawa dostępu
syscall # Wywołanie przerwania
mov %rax, %r8 # Przeniesienia wartości zwróconej przez wywołanie
# - identyfikatora otwartego pliku, do rejestru R8
# Zapis zawartości bufora out_buffer do pliku
mov $SYSWRITE, %rax
mov %r8, %rdi # Zamiast STDOUT, podajemy id otwartego pliku
mov $out_buffer, %rsi
mov $1024, %rdx
syscall
# Zamknięcie pliku
mov $SYSCLOSE, %rax # Pierwszy parametr - numer wywołania
mov %r8, %rdi # Drugi parametr - ID otwartego pliku
syscall # Wywołanie przerwania
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment