Advertisement
Guest User

ASD zad. 1

a guest
Mar 27th, 2017
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. ; ASCII z sumy kontrolnej klucza
  3. ; + ruchy wiezy, jezeli 1. arg to 1
  4. ; Agnieszka Pulnar
  5.  
  6. data segment
  7.    
  8.     no_args         db      "Blad: nie podano argumentow.$"
  9.     not_en          db      "Blad: podano za malo argumentow. Odpowiednia ilosc: 2.$"  
  10.     too_many        db      "Blad: podano za duzo argumentow. Odpowiednia ilosc: 2.$"
  11.     a1_bad          db      "Blad: pierwszy argument jest nieprawidlowy. Dopuszczalny jest jeden znak: 0/1.$"  
  12.     a2_bad          db      "Blad: klucz jest nieprawidlowy. Poprawny zapis w kodzie szesnastkowym to 32 znaki a-f, 0-9.$"
  13.    
  14.    
  15.     buf             db      150 dup ('$')               ; tablica na dane wejsciowe, maks 150 znakow parametrow
  16.     num_of_args     db      0h                          ; liczba wprowadzonych argumentow
  17.     which_vers      db      ?                           ; flaga w ktorej wersji ma pracowac program - oryginalnej czy z modyfikacja (oryginalna 30h - '0' w tabeli ASCII,
  18.                                                         ; zmodyfikowana 31h - '1' w tabeli ASCII)
  19.                                                        
  20.     key             db      16 dup (?)                  ; tablica na 16 bajtow przekonwertowanego klucza
  21.    
  22.     chessboard      db      153 dup (0)                 ; tabela przechowujaca info o polach 'szachownicy', ktore bedzie odwiedzac goniec/wieza -
  23.                                                         ; liczba odwiedzin (na poczatku 0) -> konkretne znaczki z tabeli 'symbols'
  24.                                                         ; 17 kolumn * 9 wersow
  25.    
  26.  
  27.     symbols         db      ' ','.','o','+','=','*','B','O','X','@','%','&','#','/','^'         ; tabela symboli oznaczajacych liczbe odwiedzin pola
  28.     finish          db      ?                           ; pole, na ktorym zakonczy wedrowke figura (0-152d)
  29.    
  30.     top             db      "+--[ RSA 1024]----+$"      ; elementy do narysowania ASCII arta, top sie zepsul
  31.     crlf            db      10d, 13d, '$'               ; 10d - LF (koniec linii), 13d - CR (powrot karetki)
  32.     end_of_fgp      db      "+-----------------+$" 
  33.     top2            db      "+--[ RSA 1024]----+$"
  34.     statement       db      "ASCII-art tego klucza wyglada tak:$"
  35.    
  36.     args_offsets    db      20 dup (?)                  ; tabele: offsetow, dlugosci argumentow                                
  37.     args_lengths    db      20 dup (?)                                                     
  38.     input_bytes     db      ?                           ; liczba bajtow wprowadzonych w linii komend                               
  39.    
  40. data ends
  41.  
  42.  
  43. code segment
  44.  
  45.     start:
  46.         assume cs:code, ds:data, ss:sstack
  47.        
  48.         mov ax,seg stack_ptr                            ; przygotowanie stosu
  49.         mov ss,ax      
  50.         mov sp,offset stack_ptr
  51.  
  52.         mov ax, seg data                                ; bohater mojego parsera!!
  53.         mov ds, ax
  54.        
  55.         call read                                       ; wywolanie funkcji
  56.         call check_args
  57.         call convert_to_bin
  58.         call go_thru_bytes
  59.         call fingerprint
  60.         call show_fingerprint
  61.         call end_of_prog
  62.  
  63. ; ===== PARSER =====
  64.  
  65.     ; ===== 1. WCZYTAJ ARGUMENTY =====
  66.     ; pobiera znaki z linii komend, sprawdza czy bialy i zjada biale, zapisuje parametry w tabicy argumentow 'buf', jesli brak argumentow -> alert,
  67.     ; zlicza argumenty -> num_of_args, wypelnia tablice offsetow (pierwszych znakow) argumentow (args_offsets) oraz tablice dlugosci kolejnych argumentow (args_lengths)
  68.    
  69.     read proc  
  70.         push ax                             ; odkladam dotychczasowe wartosci rejestrow na stosie, aby ich nie utracic (przy .286 mozna tez pusha i popa, wtedy jeszcze sp i bp)
  71.         push bx                                                                    
  72.         push cx                                                                    
  73.         push dx                                                                    
  74.         push di                                                                    
  75.         push si    
  76.        
  77.         xor ax, ax                          ; czyszcze rejestry, ktore za chwile wykorzystam
  78.         xor bx, bx
  79.         xor cx, cx
  80.         xor di, di                                                             
  81.         xor si, si                                                                                                                         
  82.    
  83.         mov bl, byte ptr es:[80h]           ; do bl kopiuje liczbe znakow w linii komend - PSP: 80h (ile znakow podalismy w linii komend)
  84.                                             ; 81h (spacja), 82h (od niego kolejno wprowadzone argumenty)
  85.         cmp bl, 1h                                                             
  86.         jb alert_no_args                    ; jesli mamy mniej niz 1 znak, to nie podano argumentow -> komunikat i wyjscie                                     
  87.    
  88.         ; wpp -> przechwytujemy argumnty do przygotowanej tablicy
  89.        
  90.         mov si, offset buf                  ; ustawiam offset na tablice na argumenty (=lea si,buf - mniej optymalne, do obliczen!), znak -> si                            
  91.         mov cx, offset args_offsets         ; umieszczam w cx offset tablicy offsetow argumentow
  92.        
  93.         dec bx                              ; bx - liczba bajtow/znakow z linii komend
  94.                                             ; dekrementuje, by pominac spacje pod offsetem 81h
  95.         mov word ptr ds:[input_bytes], bx   ; otrzymana liczbe bajtow zapisuje do przygotowanej zmiennej                                       
  96.  
  97.         mov al, byte ptr es:[82h]           ; pierwszy znak z linii komend -> al                                           
  98.         call check_if_white                 ; sprawdz, czy jest bialym znakiem                         
  99.         cmp ah, 0h                          ; flaga: 0=nie bialy, 1=bialy -> trzeba go zjesc
  100.         je get_the_char                     ; jesli znak nie jest bialy, przetwarzamy go
  101.         ; jne -> zjedz bialy znak
  102.        
  103.        
  104.         eat:                                ; dla bialego znaku
  105.             call eat_it                             ; lec po bialych znakach dopoki nie napotkasz nie bialego, di - licznik sprawdzonych znakow                                
  106.             cmp di, word ptr ds:[input_bytes]       ; czy sprawdzilismy juz wszystkie wprowadzone znaki?                                       
  107.             je finish_parsing                       ; jesli tak, konczymy
  108.            
  109.         get_the_char:                       ; dla pierwszego nie bialego znaku po bialych (pierwszego znaku nowego argumentu)                                  
  110.             push bx
  111.             push dx
  112.             push di
  113.            
  114.             push ax
  115.            
  116.             mov di, cx                          ; teraz di -  wskaznik kolejnego wolnego miejsca w tablicy offsetow                                                                        
  117.             mov word ptr ds:[di], si            ; zapisz offset tego argumentu w tablicy offsetow                                      
  118.             add cx, 2h                          ; przy kolejnym wywolaniu zwieksz wskaznik tablicy args_offsets o 16 bitow, czyli dlugosc kolejnego offsetu                                                
  119.             inc num_of_args                     ; inkrementuj liczbe argumentow                                
  120.             xor dl, dl                          ; wyzeruj licznik dlugosci argumentu, bo bedziemy go przegladac                                    
  121.                
  122.             pop ax                                                                     
  123.             pop di
  124.                
  125.             characters:                             ; przetwarzaj nowy argument
  126.                 mov byte ptr ds:[si], al            ; zapisz nie bialy znak do tablicy argumentow                              
  127.                 inc dl                              ; dl - licznik dlugosci aktualnego argumentu - zwiekszamy                                  
  128.                 inc di                              ; di - licznik znakow z linii komend - zwiekszamy (przeskocz na kolejny znak z linii komend)               
  129.                 cmp di, word ptr ds:[input_bytes]   ; czy sprawdzilismy juz wszystkie wprowadzone znaki?                                                               
  130.                 je fin                              ; jesli tak, konczymy                                  
  131.  
  132.                 inc si                              ; wpp -> przesuwamy wskaznik w tablicy argumentow                                                  
  133.                 mov al, byte ptr es:[82h + di]      ; pobierz kolejny znak z linii komend                                  
  134.                 xor ah, ah                          ; zerujemy ah -> flaga
  135.                 call check_if_white                                                    
  136.                 cmp ah, 0h                          ; jesli kolejny znak nie jest bialy, dalej iterujemy po argumencie                                 
  137.             je characters                                                              
  138.             ; wpp (koniec argumentu):
  139.            
  140.             fin:   
  141.                 push di                                                                
  142.                 inc si                              ; przesun wskaznik w tablicy argumentow - rozdzielamy argumenty dolarami                                                               
  143.                 mov di, offset args_lengths                                
  144.                 mov ax, word ptr ds:[num_of_args]   ; numer ostatniego argumentu -> ax                                                                                                 
  145.                 add di, ax     
  146.                 dec di                              ; di wskazywal wczesniej na 1. argument
  147.                 mov byte ptr ds:[di], dl            ; zapisz dlugosc ostatniego argumentu                              
  148.                 pop di
  149.                 pop dx
  150.                 pop bx 
  151.                 cmp di, word ptr ds:[input_bytes]   ; czy sprawdzilismy juz wszystkie wprowadzone znaki?                                                               
  152.         jne eat                                     ; jesli nie, jedz biale znaki dopoki nie trafisz na kolejny arg                            
  153.            
  154.         jmp finish_parsing
  155.        
  156.         check_if_white proc             ; otrzymuje znak w al, sprawdzam, czy znak jest bialy
  157.             xor ah, ah                  ; zeruje, w ah ustawie za chwile flage - 1=bialy, 0=nie bialy
  158.             cmp al, 20h                 ; 20h - spacja w tabeli ASCII                                  
  159.             je white                                                                       
  160.             cmp al, 9h                  ; 9h - tabulator w tabeli ASCII                                            
  161.             je white                                                           
  162.             ret    
  163.            
  164.             white:
  165.                 mov ah, 1h      ; ustawiam flage                                                       
  166.                 ret
  167.         check_if_white endp
  168.        
  169.         eat_it proc                     ; otrzymuje w di licznik sprawdzonych znakow                                                                               
  170.             push bx
  171.            
  172.             its_white:
  173.                 inc di                              ; inkrementujemy liczbe sprawdzonych znakow (bialy, wiec pomijamy)                                                         
  174.                 cmp di, word ptr ds:[input_bytes]   ; czy sprawdzilismy juz wszystkie wprowadzone znaki?                                                   
  175.                 je exit                             ; jesli tak, konczymy                          
  176.                 mov al, byte ptr es:[82h + di]      ; wpp: pobieramy do akumulatora nastepny znak z linii komend                   
  177.                 xor ah, ah                          ; zerujemy ah -> ustawimy flage        
  178.                 call check_if_white                                                        
  179.                 cmp ah, 1h                                                         
  180.             je its_white                            ; jesli bialy, jedz dalej, dopoki nie napotkasz nie bialego
  181.            
  182.             exit:
  183.                 pop bx
  184.                 ret
  185.         eat_it endp
  186.        
  187.         alert_no_args:
  188.             mov ax, seg no_args
  189.             mov ds, ax
  190.             mov dx, offset no_args
  191.             mov ah, 9h                          ; funkcja int 21,9 wypisuje odpowiedni komunikat z ds:dx, konczymy
  192.             int 21h
  193.             pop si
  194.             pop di
  195.             pop dx
  196.             pop cx
  197.             pop bx
  198.             call end_of_prog
  199.            
  200.             finish_parsing:
  201.                 pop si              ; przywracam pierwotne wartosci rejestrow
  202.                 pop di
  203.                 pop dx
  204.                 pop cx
  205.                 pop bx
  206.                 pop ax
  207.                 ret
  208.        
  209.     read endp
  210.  
  211.  
  212.     ; ===== 2. SPRAWDZ POPRAWNOSC ARGUMENTOW =====
  213.     ; sprawdza, czy wpowadzone argumenty sa poprawne: czy sa dokladnie 2, czy 1. ma dlugosc 1 i czy sklada sie z 0 lub 1, czy 2. ma dlugosc 32 i czy ma odpowiednie znaki...
  214.     ; zamienia znaki z klucza na wlasciwe cyfry szesnastkowe
  215.    
  216.     check_args proc        
  217.         push di             ; odkladam dotychczasowe wartosci rejestrow na stosie, aby ich nie utracic
  218.         push si
  219.         push bx
  220.         push cx
  221.         push dx
  222.        
  223.         ; czy wprowadzono prawidlowa liczbe argumentow?
  224.         mov al, num_of_args
  225.         cmp al, 2h                                                                                                 
  226.         jb not_enough           ; jezli mniej niz 2, to za malo
  227.         ja tumany               ; jesli wiecej niz 2, to za duzo
  228.            
  229.         ; czy argument 1. (indeks 0. w tablicy) ma dlugosc 1?                                                  
  230.         mov di, offset args_lengths                                                    
  231.         mov ah, byte ptr ds:[di]                                                       
  232.         cmp ah, 1h                  ; dlugosc 1. parametru -> ah                                               
  233.         jne ar1                     ; jesli rozna od 1, to argument niepoprawny
  234.            
  235.         ; czy argument 1. sklada sie z 0 lub 1?                                        
  236.         mov si, offset args_offsets                                                    
  237.         mov di, word ptr ds:[si]    ; do di zaladuj offset 1. argumentu,  czyli domniemanej flafgi                                         
  238.         mov al, byte ptr ds:[di]    ; pierwszy parametr -> al                                          
  239.         cmp al, 30h                 ; 30h = kod '0' w tabeli ASCII                                         
  240.         jb ar1                      ; jesli kod "mniejszy niz 0", to argument jest niepoprawny
  241.         cmp al, 31h                 ; 31h = kod '1' w tabeli ASCII
  242.         ja ar1                      ; jesli kod "wiekszy niz 1", jw.                               
  243.            
  244.         ; czy argument 2. (indeks 1. w tablicy) ma dlugosc 32?
  245.         mov di, offset args_lengths            
  246.         inc di                                                                                                         
  247.         mov ah, byte ptr ds:[di]    ; dlugosc 2. parametru -> ah                                                   
  248.         cmp ah, 32d                                                            
  249.         jne ar2                     ; jesli rozna od 32, to argument niepoprawny                       
  250.            
  251.         ; czy argument 2. sklada sie z odpowiednich znakow?
  252.         mov si, word ptr offset args_offsets                                                       
  253.         mov di, word ptr ds:[si+2]  ; offset 2. arg. -> di                                         
  254.         dec di                      ; zmniejszam di o 1, zeby nie pominac 1. znaku w 1. przbiegu petli                                     
  255.         xor cx,cx                   ; zerujemy cx: bedzie licznikiem - mamy 32 znaki do sprawdzenia                                    
  256.            
  257.             go_thru_key:
  258.                 inc di              ; przesun wskaznik na kolejny znak                                         
  259.                 inc cx              ; sprawdzilismy kolejny znak -> inkrementujemy licznik                                             
  260.                
  261.                 mov al, byte ptr ds:[di]        ; zaladuj do al kolejny znak klucza                                    
  262.                 cmp al, 30h                     ; 30h =  kod '0'    w tabeli ASCII
  263.                 jb ar2                          ; jesli kod znaku "mniejszy niz 0", to klucz niepoprawny                           
  264.                 cmp al, 39h                     ; 39h = kod '9' w tabeli ASCII                                             
  265.                 jbe from_0_to_9                                                            
  266.                 cmp al, 61h                     ; 61h = kod 'a' w tabeli ASCII                                 
  267.                 jb ar2                          ; jesli kod "mniejszy niz a", to klucz niepoprawny                 
  268.                 cmp al, 66h                     ; 66h = kod 'f' w tabeli ASCII                             
  269.                 ja ar2                          ; jesli kod "wiekszy niz f", jw.
  270.                
  271.                 from_a_to_f:                    ; zapisz litere z klucza w postaci szesnastkowej nie-ASCII
  272.                     mov al, 61h                 ; 61h = kod 'a' w ASCII                
  273.                     sub byte ptr ds:[di], al    ; aby otrzymac cyfre szesnastkowa <10,15>, musimy od jej kodu ASCII odjac kod 'a' i dodac 10
  274.                     add byte ptr ds:[di], 0ah
  275.                     cmp cx, 32d                 ; czy przeszlismy juz przez wszystkie 32 znaki?
  276.             jb go_thru_key                      ; jesli nie, przegladaj dalej
  277.            
  278.                 from_0_to_9:                    ; zapisz cyfre z klucza w postaci szesnastkowej nie-ASCII
  279.                     mov al, 30h                
  280.                     sub byte ptr ds:[di], al    ; aby uzyskac cyfre, od ich kodu ASCII odejmujemy kod '0'=30h
  281.                     cmp cx, 32d                 ; czy przeszlismy juz przez wszystkie 32 znaki?
  282.             jb go_thru_key                      ; jesli nie, przegladaj dalej
  283.                
  284.         jmp exit                        ; mamy 32 znaki -> zakoncz sprawdzanie
  285.            
  286.             not_enough:                 ; komunikat gdy za malo arg.
  287.                 mov ax, seg not_en
  288.                 mov ds, ax
  289.                 mov dx, offset not_en
  290.                 jmp alert_exit
  291.            
  292.             tumany:                     ; komunikat gdy za duzo arg.
  293.                 mov ax, seg too_many
  294.                 mov ds, ax
  295.                 mov dx, offset too_many
  296.                 jmp alert_exit
  297.                
  298.             ar1:                        ; komunikat o nieprawidlowym argumencie 1.
  299.                 mov ax, seg a1_bad
  300.                 mov ds, ax
  301.                 mov dx, offset a1_bad
  302.                 jmp alert_exit
  303.                
  304.             ar2:                        ; komunikat o nieprawidlowym argumencie 2.
  305.                 mov ax, seg a2_bad
  306.                 mov ds, ax
  307.                 mov dx, offset a2_bad
  308.                 jmp alert_exit
  309.            
  310.             alert_exit:                 ; wypisz komunikat i zakoncz                                                           
  311.                 mov ah,9                                                               
  312.                 int 21h                                                                
  313.                 call end_of_prog                                                       
  314.         exit:
  315.         pop dx                          ; przywracam pierwotne wartosci rejestrow
  316.         pop cx
  317.         pop bx
  318.         pop si
  319.         pop di
  320.         ret
  321.     check_args endp
  322.    
  323. ; ===== UTWORZ FINGERPRINT =====
  324.        
  325.         ; ===== 3. KONWERTUJ CIAG BAJTOW W ZAPISIE HEKSADECYMALNYM -> POSTAĆ BINARNA =====
  326.         ; opracowuje tabele key zawierajaca postac binarna klucza, laczy 4-bitowe cyfry heksadecymalne w 16 par
  327.        
  328.         convert_to_bin proc                                                            
  329.             push ax                 ; odkladam dotychczasowe wartosci rejestrow na stosie, aby ich nie utracic
  330.             push cx
  331.             push dx
  332.             push si
  333.             push di
  334.            
  335.             call which_version      ; sprawdz, w ktorej wersji ma pracowac program
  336.            
  337.             mov si, word ptr offset args_offsets                                                   
  338.             mov di, word ptr ds:[si+2]      ; w di umieszczam offset 2. argumentu, czyli klucza, ktory konwertujemy                                        
  339.             mov si, offset key              ; w si umieszczam offset tablicy na zapis binarny konwertowanego klucza
  340.                
  341.             mov cx, 16d                     ; mamy 16 bajtow do przekonwertowania (32 cyfry hex* 4 bity)
  342.                
  343.             convert_pair:
  344.                 mov al, byte ptr ds:[di]    ; pobierz pierwsza 4-bitowa cyfre z pary                                                                                               
  345.                 push cx                     ; zachowaj wartosc licznika z petli
  346.                 mov cl, 4h                                                                     
  347.                 rol al, cl                  ; rotuj zawartosc al o 4 w lewo, a puste miejsca wypelnij "0" z przodu = shl al, cl                                    
  348.                 pop cx                      ; przywroc licznik z petli
  349.                 mov dl, al                  ; al -> dl         
  350.                 inc di
  351.                 mov al, byte ptr ds:[di]    ; do al pobierz druga cyfre z pary                                                                                             
  352.                 add al, dl                  ; dodaj do siebie obie cyfry -> mamy bajt                                          
  353.                 mov byte ptr ds:[si], al    ; umiesc w tablicy binarnego klucza    
  354.                 inc di
  355.                 inc si                                                             
  356.             loop convert_pair      
  357.                    
  358.             pop di                   ; przywracam pierwotne wartosci rejestrow
  359.             pop si
  360.             pop dx
  361.             pop cx
  362.             pop ax
  363.             ret
  364.         convert_to_bin endp
  365.        
  366.         ; ===== 4. SPRAWDZ, W JAKIEJ WERSJI MA PRACOWAC PROGRAM =====
  367.         ; w zmiennej which_vers okresla precyzyjnie, czy program ma dzialac normalnie (ruchy gonca), czy w wersji zmodyfikowanej (ruchy wiezy)
  368.        
  369.         which_version proc
  370.             mov si, word ptr offset args_offsets    ; pobierz offset 1. parametru                                                  
  371.             mov di, word ptr ds:[si]                                                       
  372.             mov al, byte ptr ds:[di]                ; rzutuj typ
  373.             mov byte ptr ds:[which_vers], al        ; w zmiennej-fladze ustaw, ktora wersje programu mamy wykonac:
  374.                                                     ; (oryginalna 30h - '0' w tabeli ASCII, zmodyfikowana 31h - '1' w tabeli ASCII)
  375.             ret
  376.         which_version endp
  377.  
  378.        
  379.         ; ===== 5. ANALIZUJ BITY -> RUCHY NA SZACHOWNICY =====
  380.         ; przejmuje po kolei od prawej po bicie pary bitow (00, 01, 10 lub 11) i na ich podstawie okresla ruch gonca lub wiezy
  381.         ; ruchy gonca: 00 - w lewo i w gore, 01 - w prawo i w gore, 10 - w lewo i w dol, 11 - w prawo i w dol
  382.         ; ruchy wiezy: 00 - w gore, 01 - w prawo, 10 - w lewo, 11 - w dol (przesuniete o 45* zgodnie z ruchem wskazowek zegara)
  383.        
  384.         go_thru_bytes proc                                                         
  385.             push di                                 ; odkladam dotychczasowe wartosci rejestrow na stosie, aby ich nie utracic
  386.             push dx
  387.             push si
  388.             push cx
  389.             push bx
  390.                
  391.                 mov di, offset key                  ; przygotuj przekonwertowany klucz                                 
  392.                 mov si, 76d                         ; si - pozycja na szachownicy - startujemy na srodku planszy, czyli polu nr 76                                 
  393.                 mov cx, 16d                         ; mamy do przebiegniecia 16 bajtow klucza, cx bedzie licznikiem -> 0                                       
  394.                 mov al, byte ptr ds:[which_vers]    ; w ktorej wersji ma dzialac program?
  395.                 cmp al, 31h                                                            
  396.                 je rook                                                                
  397.                
  398.                 bishop:                             ; standardowa wersja programu z ruchami gonca                                                      
  399.                     mov bl, byte ptr ds:[di]        ; wez pare bitow                               
  400.                     push cx            
  401.                     mov cx, 4h                      ; kazdy z 16 bajtow klucza zawiera 4 pary bitow, cx po raz kolejny licznikiem, wiec wczesniej pushujemy
  402.                    
  403.                     b_move:                                                        
  404.                         push dx
  405.                         shr bl, 1h                  ; przesuniecie bitow w prawo -> do cf wedruje mlodszy bit z pary:
  406.                         jc right?                   ; _1 - w prawo i ?, _0 - w lewo i ?
  407.                         jnc left?
  408.    
  409.                         right?:                     ; _1
  410.                             call go_right
  411.                             shr bl, 1h              ; kolejne przesuniecie bitow w prawo -> do cf wedruje bit odpowiedzialny za ruch gora-dol
  412.                             jc down                 ; 11 - w prawo i w gore
  413.                             jnc up                  ; 01 - w prawo i w dol
  414.                            
  415.                         left?:                      ; _0
  416.                             call go_left           
  417.                             shr bl, 1h              ; kolejne przesuniecie bitow w prawo -> do cf wedruje bit odpowiedzialny za ruch gora-dol
  418.                             jc down                 ; 10 - w lewo i w dol
  419.                             jnc up                  ; 00 - w lewo i w gore
  420.                            
  421.                         up:
  422.                             call go_up
  423.                             jmp move_n_fin1
  424.                                
  425.                         down:
  426.                             call go_down
  427.                             jmp move_n_fin1
  428.                            
  429.                         move_n_fin1:
  430.                         call MOVE
  431.                         pop dx
  432.                                                                        
  433.                     loop b_move    
  434.                    
  435.                     pop cx 
  436.                     inc di                          ; przesun wskaznik na nastepna pare
  437.                 loop bishop    
  438.                
  439.                 jmp exit                                                                   
  440.                
  441.                 rook:                               ; zmodyfikowana wersja programu - ruchy wiezy                                                          
  442.                     mov bl, byte ptr ds:[di]        ; wez pare bitow                           
  443.                     push cx
  444.                     mov cx, 4h                      ; kazdy z 16 bajtow klucza zawiera 4 pary bitow, cx po raz kolejny licznikiem, wiec wczesniej pushujemy
  445.                    
  446.                     r_move:
  447.                         push dx
  448.                         shr bl, 1h                  ; przesuniecie bitow w prawo -> do cf wedruje mlodszy bit z pary:                                                                                                                      
  449.                         jnc up?left                 ; _0 : 00 -> w górę, 10 -> w lewo, a wiec nalezy sprawdzic drugi bit
  450.                         jc down?right               ; _1 : 11 -> w dół, 01 -> w prawo, a wiec nalezy sprawdzic drugi bit
  451.                                
  452.                         down?right:
  453.                             shr bl, 1h              ; kolejne przesuniecie bitow w prawo -> drugi bit dopelnia info o kierunku ruchu                                           
  454.                             jc r_down               ; 11 - w dol                                       
  455.                             jnc r_right             ; 01 - w prawo                                         
  456.                            
  457.                         up?left:                                                   
  458.                             shr bl, 1h              ; kolejne przesuniecie bitow w prawo -> drugi bit dopelnia info o kierunku ruchu                                                               
  459.                             jc r_left               ; 10 - w lewo                                  
  460.                             jnc r_up                ; 00 - w gore                                                  
  461.                                
  462.                             r_right:
  463.                                 call go_right                                                          
  464.                                 jmp move_n_fin2                                        
  465.                             r_up:
  466.                                 call go_up                                                             
  467.                                 jmp move_n_fin2                                        
  468.                             r_down:
  469.                                 call go_down                                                           
  470.                                 jmp move_n_fin2                                        
  471.                             r_left:
  472.                                 call go_left                                                           
  473.                                 jmp move_n_fin2                                        
  474.                                
  475.                             move_n_fin2:
  476.                             call MOVE                                                              
  477.                             pop dx     
  478.                            
  479.                         loop r_move
  480.                        
  481.                     pop cx
  482.                     inc di                          ; przesun wskaznik na nastepna pare
  483.                 loop rook  
  484.  
  485.                 jmp exit
  486.                
  487.             exit:
  488.                 mov word ptr ds:[finish], si    ; zapisz koncowa pozycje figury w odpowiedniej zmiennej                                            
  489.                 pop bx                          ; przywracam pierwotne wartosci rejestrow
  490.                 pop cx
  491.                 pop si
  492.                 pop dx
  493.                 pop di
  494.                 ret
  495.         go_thru_bytes endp
  496.  
  497.         ; === 5a. >>> RUCH W PRAWO <<< ===
  498.         ; przesuwa figure o 1 w prawo
  499.         go_right proc
  500.             push dx                     ; mlodsza czesc dx wykorzystamy przy dzieleniu
  501.             mov ax, si                  ; w ax umiesc aktualna pozycje na szachownicy (jej numer 0-152)                                                    
  502.             mov dl, 17d                                                            
  503.             div dl                      ; DIV ax/dl = al r. ah                                         
  504.             cmp ah, 16d                                                
  505.             je exit                     ; jesli reszta z dzielenia jest rowna 16, to znaczy ze jestesmy przy prawej krawedzi, czyli dalej nie mozemy sie ruszyc -> wychodzimy          
  506.             inc si                      ; wpp -> przesuwamy o 1 w prawo, czyli dodajemy 1 do licznika aktualnej pozycji i tez wychodzimy
  507.            
  508.             exit:
  509.                 pop dx
  510.                 ret
  511.         go_right endp
  512.        
  513.         ; === 5b. >>>>> RUCH W LEWO <<<<< ===
  514.         ; przesuwa figure o 1 w lewo
  515.         go_left proc
  516.             push dx                     ; mlodsza czesc dx wykorzystamy przy dzieleniu
  517.             mov ax, si                  ; w ax umiesc aktualna pozycje na szachownicy                                      
  518.             mov dl, 17d                                                        
  519.             div dl                      ; DIV ax/dl = al r. ah                                             
  520.             cmp ah, 0h                  ; jesli reszta z dzielenia jest rowna 0, to znaczy ze jestesmy przy lewj krawedzi, czyli dalej nie mozemy sie ruszyc    -> wychodzimy                                      
  521.             je exit                                                            
  522.             dec si                      ; wpp -> przesuwamy o 1 w lewo, czyli odejmujemy 1 od licznika aktualnej pozycji i tez wychodzimy
  523.            
  524.             exit:
  525.                 pop dx
  526.                 ret
  527.         go_left endp
  528.        
  529.         ; === 5c. >>> RUCH W GORE <<< ===
  530.         go_up proc
  531.             cmp si, 16d                                                            
  532.             jbe exit1                   ; jesli figura znajduje sie na polu 0-16, to nie moze juz isc w gore -> wychodzimy                                 
  533.             sub si, 17d                 ; wpp -> przesuwamy o rzad, czyli 17 pól do tylu, a wiec odejmujemy 17 od licznika aktualnej poz i tez wychodzimy
  534.                
  535.             exit1:
  536.                 ret
  537.         go_up endp
  538.  
  539.         ; === 5d. >>> RUCH W DOL <<< ===
  540.         go_down proc
  541.             cmp si, 136d                                                                       
  542.             jae exit1                   ; jesli figura znajduje sie na polu 136-152, to nie moze juz isc w dol -> wychodzimy                                           
  543.             add si, 17d                 ; wpp -> przesuwamy o rzad, czyli 17 pól do przodu, a wiec dodajemy 17 do licznika aktualnej poz i tez wychodzimy
  544.            
  545.             exit1:
  546.                 ret
  547.         go_down endp
  548.                
  549.         ; === 5e. Wykonaj ruch ===
  550.         ; inkrementuje licznik odwiedzonego w wyniku powyzszego ruchu pola
  551.         MOVE proc
  552.             push di
  553.             push ax
  554.            
  555.             mov di, offset chessboard   ; przygotuj adres szachownicy                      
  556.             add di, si                  ; adr. tabl. przesuwamy o aktualna pozycje po wykonaniu ruchow z pary bitow                                
  557.             inc byte ptr ds:[di]        ; zwiekszamy wartosc licznika w odpowiednim polu szachownicy   
  558.            
  559.             pop ax
  560.             pop di
  561.             ret
  562.         MOVE endp
  563.        
  564.  
  565.         ; ===== 6. GENERUJ FINGERPRINT =====
  566.         ; zamienia liczniki w poszczegolnych komorkach tablicy=szachownicy na okreslone znaki do wygenerowania fingerprinta
  567.        
  568.         fingerprint proc                                                               
  569.                 push cx                             ; odkladam dotychczasowe wartosci rejestrow na stosie, aby ich nie utracic
  570.                 push si
  571.                 push di
  572.                 push ax
  573.                
  574.                 mov cx, 153d                        ; musimy wygenerowac symbol dla kazdego z 153 potencjalnie odwiedzonych pol szachownicy
  575.                 mov si, offset chessboard           ; przygotuj szachownice (jej offset)
  576.                 push si
  577.                 mov di, offset symbols              ; przygotuj tablice znakow do wypelniania szachownicy (jej offset)
  578.                
  579.                 nums_into_chars:
  580.                     push di                         ; zachowuje offset tablicy symboli na pozniej, bo bede go modyfikowac
  581.                     xor ax, ax
  582.                     mov al, byte ptr ds:[si]        ; pobierz do al liczbe odwiedzin dla kolejnego pola
  583.                     cmp al, 14d                
  584.                     jbe upto14                      ; jesli liczba odwiedzin <= 14, to przepisujemy znaczek z tabelki
  585.                     mov al, 14d                     ; a jesli > 14, to postepujemy jak dla 14 odwiedzin
  586.                     upto14:
  587.                         add di, ax                  ; do poczatku tablicy wklejanych znakow dodajemy liczbe odwiedzin pola o offsecie si,
  588.                                                     ;                                   dzieki czemu dostajemy sie do konkretnego znaku
  589.                         mov ah, byte ptr ds:[di]    ; znaczek -> ah
  590.                         mov byte ptr ds:[si], ah    ; ah -> odpowiednie miejsce na szachownicy
  591.                         inc si                      ; przesun wskaznik na kolejne pole
  592.                     pop di                          ; wroc do poczatku tablicy znaczkow
  593.                 loop nums_into_chars
  594.                
  595.                 pop si                              ; do si ponownie trafia offset szachownicy
  596.                 mov byte ptr ds:[si+76d], 53h       ; w srodkowym polu umiesc znaczek startu (53h = "S' w tabeli ASCII)
  597.                 mov di, word ptr ds:[finish];
  598.                 add si, di                          ; do offsetu szachownicy dodaj offset ostatniego polozenia figury
  599.                 mov byte ptr ds:[si], 45h           ; umiesc tam znaczek konca (45h = "E" w tabeli ASCII)
  600.        
  601.                 pop ax                              ; przywracam pierwotne wartosci rejestrow
  602.                 pop di
  603.                 pop si
  604.                 pop cx
  605.             ret
  606.         fingerprint endp
  607.  
  608.        
  609.         ; ===== 7. RYSUJ FINGERPRINT =====
  610.         ; "dzieli" jednowymiarowa tablice="szachownice" na 9 wersow po 17 znakow, wypisujac na ekranie stworzona grafike ASCII, dodaje ramki
  611.        
  612.         show_fingerprint proc
  613.                 push si                     ; odkladam dotychczasowe wartosci rejestrow na stosie, aby ich nie utracic
  614.                 push cx
  615.                 push dx
  616.                 push ax
  617.                
  618.                 mov dx, offset crlf         ; nowa linia (int 21,9 wypisuje zawartosc ds:dx)
  619.                 mov ah, 9h
  620.                 int 21h
  621.                 mov dx, offset statement    ; wypisz tekst powitalny
  622.                 ;mov ah, 9h
  623.                 int 21h
  624.                 mov dx, offset crlf         ; nowa linia
  625.                 ;mov ah, 9h
  626.                 int 21h
  627.                 mov dx, offset top2         ; wypisz gorna ramke
  628.                 ;mov ah, 9h
  629.                 int 21h
  630.                 mov dx, offset crlf         ; przejdz do nowej linii -> zaczynamy wypisywanie "zawartosci" szachownicy
  631.                 ;mov ah, 9h
  632.                 int 21h
  633.                
  634.                 mov si, offset chessboard
  635.                 mov cx, 9h                  ; cx bedzie licznikiem - mamy 9 linii do wypisania
  636.                 print_line_by_line:
  637.                     push cx                 ; we wnetrzu petli odkladam cx na stos, bo po raz kolejny wykorzystam go jako licznik -
  638.                     mov cx, 17d             ; mamy bowiem 17 znakow do wypisania w kazdej linii
  639.                     mov dl, '|'             ; lewy przeg szachownicy
  640.                     mov ah, 2h              ; int 21,2 wypisuje ZNAK umieszczony w dl
  641.                     int 21h
  642.                     print_line:
  643.                         mov dl,  byte ptr ds:[si] ; wypisz znak po znaku cala linie symboli szachownicy
  644.                         inc si
  645.                         ;mov ah, 2h
  646.                         int 21h
  647.                     loop print_line
  648.                    
  649.                     mov dl, '|'             ; wypisz prawy brzeg
  650.                     ;mov ah, 2h
  651.                     int 21h
  652.                     mov dx, offset crlf     ; przejdz do nowej linii
  653.                     mov ah, 9h
  654.                     int 21h
  655.                     pop cx
  656.                 loop print_line_by_line
  657.                
  658.                 mov dx, offset end_of_fgp   ; wypisz dolna ramke
  659.                 mov ah, 9h
  660.                 int 21h
  661.                
  662.                 mov dx, offset crlf         ;  nowa linia
  663.                 ;mov ah, 9h
  664.                 int 21h
  665.                
  666.                 pop ax                      ; przywracam pierwotne wartosci rejestrow
  667.                 pop dx
  668.                 pop cx
  669.                 pop si
  670.                 ret
  671.         show_fingerprint endp
  672.            
  673.  
  674.         ; ===== KONIEC PROGRAMU =====
  675.         end_of_prog proc
  676.             mov ah, 4ch         ; koniec, powrot do DOS - int 21,4c -> terminate process
  677.             int 21h
  678.             ret
  679.         end_of_prog endp
  680.  
  681.     code ends
  682.  
  683. sstack segment stack
  684.     dw 150 dup (?)              ; stos o rozmiarze 150 slow
  685.     stack_ptr dw ?
  686. sstack ends
  687.  
  688. end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement