Różne programy na zajęcia laboratoryjne z AK2
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. # Jan Potocki 2020
  2. # Definicje numerow funkcji systemowych i ich parametrow
  3. SYSEXIT64 = 60
  4. SYSREAD = 0
  5. SYSWRITE = 1
  6. STDIN = 0
  7. STDOUT = 1
  8. # Stale okreslajace rozmiar przetwarzanych danych
  9. num_length = 256
  10. # ...tego nie ruszac - inaczej stanie sie "cud nad klawiatura" :-D
  11. word_length = 8
  12. buf_length = num_length * 2
  13. num_words = num_length / word_length
  14. buf_words = buf_length / word_length
  15. .global main
  16. # Segment niezainicjalizowanych danych
  17. .bss
  18. liczba1: .space num_length
  19. liczba2: .space num_length
  20. wynik: .space buf_length
  21. # Segment kodu
  22. .text
  23. main:
  24. # Glowna petla
  25. petla:
  26. mov $SYSREAD, %rax # Wczytanie danych ze standardowego wejscia
  27. mov $STDIN, %rdi # ...funkcja systemowa read
  28. mov $liczba1, %rsi
  29. mov $buf_length, %rdx
  30. syscall
  31. # UWAGA
  32. # Tutaj wczytane zostana od razu obie liczby
  33. # liczba1 i liczba2 sa w pamieci bezposrednio po sobie...
  34. # ...i zostala przekazana do funkcji read dlugosc calego bloku
  35. cmp $buf_length, %rax # rax - liczba wczytanych bajtow
  36. jl koniec # Jezeli nie ma 512, to dane sie skonczyly
  37. xor %rsi, %rsi # rsi - licznik petli zerujacej
  38. # Petla zerujaca bufor na wynik
  39. wyzeruj:
  40. movq $0, wynik(, %rsi, 8)
  41. inc %rsi
  42. cmp $buf_words, %rsi
  43. jl wyzeruj
  44. xor %rsi, %rsi # rsi - licznik pierwszej petli
  45. # Mnozenie - petla zewnetrzna
  46. petla1:
  47. xor %rcx, %rcx # rcx - miejsce na starsza czesc wyniku
  48. # Flagi przeniesienia (potrzebne sa dwie i tego sie nie uprosci)
  49. mov $0, %r8 # r8 - dla koncowego wyniku (w pamieci)
  50. clc # RFLAGS - dla biezacego mnozenia (rejestry)
  51. pushf # ...oczywiscie z backupem na stosie
  52. xor %rdi, %rdi # rdi - licznik drugiej petli
  53. # Mnozenie - petla wewnetrzna
  54. petla2:
  55. movq liczba1(, %rsi, 8), %rax
  56. mulq liczba2(, %rdi, 8)
  57. mov %rdi, %r9 # r9 - indeks wyniku
  58. add %rsi, %r9 # (suma indeksow obu petli)
  59. # Dodanie starszej czesci wyniku z poprzedniej iteracji
  60. popf # Tutaj flagi mamy na stosie...
  61. adc %rcx, %rax
  62. pushf # ...wiec to jest proste
  63. # Przygotowanie flagi przeniesienia do sumowania wyniku (patent cz. I)
  64. cmp $1, %r8 # Tego nie mamy na stosie...
  65. je ustaw_cf1 # ...wiec musimy sprytnym sposobem ;-)
  66. clc # Przypadek bez przeniesienia
  67. jmp dodaj_wynik
  68. ustaw_cf1:
  69. stc # Przypadek z przeniesieniem
  70. # Dodawanie biezacego wyniku do pamieci
  71. # (tam po wszystkich iteracjach bedzie wynik koncowy)
  72. dodaj_wynik:
  73. adcq %rax, wynik(, %r9, 8)
  74. # Zapisanie flagi przeniesienia do sumowania wyniku (patent cz. II)
  75. jc zapisz_cf
  76. mov $0, %r8 # Jezeli przeniesienia nie bylo
  77. jmp dalej
  78. zapisz_cf:
  79. mov $1, %r8 # Jezeli przeniesienie bylo
  80. dalej:
  81. mov %rdx, %rcx # Przechowanie starszej czesci wyniku w rcx
  82. inc %rdi
  83. cmp $num_words, %rdi
  84. jl petla2 # Koniec wewnetrznej petli
  85. # Tutaj musimy sie jeszcze zajac najstarsza czescia wyniku
  86. # (z ostatniej iteracji petli wewnetrznej)
  87. inc %r9
  88. popf # Dodanie przeniesienia z sumowania rejestrow
  89. adc $0, %rcx # ...jezeli jakies zostalo
  90. # Przygotowanie flagi przeniesienia do sumowania wyniku (patent cz. I)
  91. cmp $1, %r8
  92. je ustaw_cf2
  93. clc # Przypadek bez przeniesienia
  94. jmp dodaj_najstarsze
  95. ustaw_cf2:
  96. stc # Przypadek z przeniesieniem
  97. dodaj_najstarsze:
  98. adcq %rcx, wynik(, %r9, 8)
  99. inc %rsi
  100. cmp $num_words, %rsi
  101. jl petla1 # Koniec zewnetrznej petli
  102. mov $SYSWRITE, %rax # Wypisanie wyniku na standardowe wyjscie
  103. mov $STDOUT, %rdi # ...funkcja systemowa write
  104. mov $wynik, %rsi
  105. mov $buf_length, %rdx
  106. syscall
  107. jmp petla # Koniec glownej petli
  108. # Wyjscie z programu
  109. koniec:
  110. mov $SYSEXIT64, %rax # Funkcja systemowa exit...
  111. mov $0, %rdi # ...kod zakonczenia - 0
  112. syscall