Guest User

Untitled

a guest
May 7th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. myStack segment STACK
  2.     dw 100h dup(?)
  3. myStack ends
  4.  
  5. data segment
  6.  
  7.         blad db "Blad",10,13,"$"
  8.         pomoc db "Poprawna skladnia: konkatenacja [-h|{-i plik_wejsciowy} [-o plik_wyjsciowy] [-t symbol_separacji]]",10,13,"$"
  9.         zla_skladnia db "Bledna skladnia",10,13,"$"
  10.         brak_o db "Nie podano nazwy pliku wyjsciowego!",10,13,"$"
  11.         za_duzo_o db "Podaj tylko jeden plik wejściowy. Opcja -o nie może być użyta wielokrotnie",10,13,"$"
  12.         problem_plik_wejsciowy db "Nie mozna otworzyc pliku do odczytu/zapisu",10,13,"$"
  13.        
  14.         tmp db 15 dup(0)                        ;bufor na nazwy plików wejsciowych oraz wyjsciowych
  15.         ile_wejsciowych db 0                    ;ile mamy plikow wejsciowych
  16.         plik_wyjsciowy_uchwyt dw 0              ;uchwyt do pliku wyjściowego
  17.         pliki_wejsciowe_uchwyty dw 25 dup(0)    ;uchwyty do plików wejściowych
  18.         bools_zrobione db 25 dup(0)             ;tablica plików przetworzonych
  19.         bools_czy_pierwszy db 0                 ;czy plik na wejściu jest pierwszy w linii, co oznacza brak separatora na początku
  20.         bools_wyjsciowy db 0                    ;flaga informujaca czy istnieje plik wynikowy (opcja -o)
  21.                
  22.         separator db " $"                       ;domyślnym separatorem jest spacja
  23.         znak db 0,"$"                           ;pojedynczy znak
  24.         nwln db 13,10,"$"                       ;nowa linia
  25. data ends
  26.  
  27.  
  28.  
  29. code segment
  30. start:
  31.  
  32.     main proc
  33.         mov ax,seg data     ;ustawianie segment danych
  34.         mov ds,ax
  35.         mov ax,seg myStack  ;ustawianie  segment stosu
  36.         mov ss,ax           ;linia poleceń znajduje sie w es, a jej długość w es:[80h]
  37.         xor cx,cx
  38.         mov cl,es:[80h]     ;przechwycenie długości linii komend
  39.         mov di,81h          ;parsujemy wejscie od pierwszego znaku
  40.         test cx,cx          ; sprawdzamy czy linia komend jest pusta
  41.         je throw_zla_skladnia   ;jesli pusta rzucamy blad - na ekran wypluwamy poprawne uzycie
  42.        
  43.         parsowanie:
  44.             cmp byte ptr es:[di],' '    ;jeśli pierwszy znak nie jest spacją to błąd
  45.             jne throw_zla_skladnia
  46.             inc di
  47.             dec cx
  48.             cmp byte ptr es:[di],'-'    ;jeśli kolejny znak nie jest pauzą to błąd
  49.             jne throw_zla_skladnia
  50.             inc di
  51.             dec cx
  52.            
  53.             if_its_h:                       ; czy zostal wywolany parametr -h
  54.                 cmp byte ptr es:[di],'h'
  55.                 je wyswietl_pomoc           ; jesli tak wypluj poprawną składnię
  56.                
  57.             if_its_t:                       ; czy został wywołany parametr -t
  58.                 cmp byte ptr es:[di],'t'
  59.                 jne if_its_o
  60.                 inc di
  61.                 dec cx
  62.                 cmp byte ptr es:[di],' '    ;następny znak musi być spacją
  63.                 jne throw_zla_skladnia
  64.                 inc di
  65.                 dec cx
  66.                 test cx,cx
  67.                 jbe throw_zla_skladnia      ; gdy wywolano opcję -t musi się pojawić znak lub spacja
  68.                 mov bx,offset separator
  69.                 mov al,byte ptr es:[di]     ;separator przekazujemy do al
  70.                 mov ds:[bx],al              ;separator zostaje zmieniony na ten podany w linii komend
  71.                 inc di
  72.                 dec cx
  73.                 test cx,cx
  74.                 jbe cmd_is_parsed
  75.                 jmp parsowanie
  76.                
  77.             if_its_o:                           ;czy jest to wywolanie opcji -o i podanie pliku wynikowego?
  78.                 cmp byte ptr es:[di],'o'
  79.                 jne if_its_i
  80.                 mov bx,offset bools_wyjsciowy
  81.                 cmp byte ptr ds:[bx],1          ;Sprawdzam czy nie ma już pliku wyjściowego
  82.                 je throw_za_duzo_o
  83.                 mov byte ptr ds:[bx],1          ;Zaznaczam że mam już plik wyjściowy
  84.                 inc di
  85.                 dec cx
  86.                 cmp byte ptr es:[di],' '    ;następny znak musi być spacją
  87.                 jne throw_zla_skladnia
  88.                 inc di
  89.                 dec cx
  90.                 cmp byte ptr es:[di],' '    ;Jeśli nie ma nazwy pliku wyjściowego to jest to błąd
  91.                 je throw_brak_o
  92.                 cmp byte ptr es:[di],'-'    ;następnym znakiem nie może być "-"
  93.                 je throw_zla_skladnia
  94.                
  95.                     ;przekopiowanie nazwy pliku wyjściowego do tmp    
  96.                 mov bx,offset tmp       ;W bx przechowuje offset nazwy pliku wynikowego
  97.                 xor si,si               ;Aktualny indeks w tablicy tmp
  98.                 xor ah,ah
  99.                 while_not_space:
  100.                     test cx,cx 
  101.                     jbe after_1_while   ;Koniec linii poleceń
  102.                     mov al,byte ptr es:[di]
  103.                     cmp al,' '          ;jeśli to spacja konczymy kopiowane
  104.                     je after_1_while
  105.                     mov ds:[bx+si],al   ;Wpisuje sobie znak
  106.                     inc di
  107.                     inc si
  108.                     dec cx
  109.                     jmp while_not_space
  110.                     after_1_while:      ;tworzenie i zapis uchwytu do pliku wyjściowego
  111.                         mov byte ptr ds:[bx+si],0
  112.                         xor si,si                           ;Pozycja do zapisu uchwytu to zero
  113.                         mov bx,offset plik_wyjsciowy_uchwyt ;Tu otrzymam uchwyt
  114.                         mov al,010b                         ;Do odczytu i zapisu
  115.                         mov dx,offset tmp
  116.                         call fopen
  117.                         test cx,cx
  118.                         jbe cmd_is_parsed
  119.                         jmp parsowanie
  120.                        
  121.             if_its_i:                   ;czy jest to wywolanie opcji -o i podanie pliku wejsciowego?
  122.                 cmp byte ptr es:[di],'i'    ;jeśli kolejnym znakiem nie jest "i" - błąd
  123.                 jne throw_zla_skladnia
  124.                 inc di
  125.                 dec cx
  126.                 test cx,cx
  127.                 jbe throw_zla_skladnia
  128.                 cmp byte ptr es:[di],' ' ;następny znak musi być spacja
  129.                 jne throw_zla_skladnia
  130.                 inc di
  131.                 dec cx
  132.                 cmp byte ptr es:[di],'-' ; następnym znakiem nie może być "-"
  133.                 je throw_zla_skladnia
  134.                 mov bx,offset tmp       ; tu trzymam offset bufora na nazwę pojedynczego pliku wejsćiowego
  135.                 xor si,si               ;tu trzymam aktualną pozycję w tablicy bufora
  136.                 xor ax,ax
  137.                 while_not_space_2:      ;Wykonuje sie dopóki parsowany znak to nie spacja lub cx == 0
  138.                     test cx,cx
  139.                     jbe after_while
  140.                     mov al,byte ptr es:[di]     ;kopiuje znak do al
  141.                     cmp al,' '                  ;jeśli aktualny znak to spacja
  142.                     je after_while
  143.                     mov ds:[bx+si],al           ;znak z al kopiuje do bufora
  144.                     inc di
  145.                     inc si
  146.                     dec cx
  147.                     jmp while_not_space_2
  148.                 after_while:
  149.                     mov byte ptr ds:[bx+si],0   ;Poprzednia nazwa mogła być dłuższa
  150.                     mov bx,offset ile_wejsciowych
  151.                     xor ax,ax
  152.                     mov al,byte ptr ds:[bx]     ;Pobieram numer uchwytu do zapisu
  153.                     mov si,ax
  154.                     shl si,1                    ;Przemnażam si przez 2 bo lece po wordach
  155.                     inc al
  156.                     mov byte ptr ds:[bx],al     ;Zwiękaszam numer w zmiennej
  157.                     mov bx,offset pliki_wejsciowe_uchwyty  
  158.                     xor ax,ax
  159.                     mov dx,offset tmp
  160.                     mov al,000b                 ;Tylko do odczytu
  161.                     call fopen
  162.                     test cx,cx
  163.                     jbe cmd_is_parsed
  164.                     jmp parsowanie
  165.                 jmp parsowanie
  166.                
  167.             cmd_is_parsed:                     
  168.            
  169.                 ;tutaj posiadamy wszystkie potrzebne uchwyty do plików
  170.                
  171.                 xor di,di   ;numer odpowiedniego pliku wejściowego do przerabiania
  172.                 mov bx,offset bools_czy_pierwszy
  173.                 cmp byte ptr ds:[bx],1      ;jeśli pierwszy to znaczy, że nic nie przerobiiśmy -> koniec
  174.                 je fclose
  175.                 mov byte ptr [bx],1
  176.                
  177.                 for_in_files:               ;przepisujemy kolejne linie z plików wejściowych
  178.                     xor ax,ax
  179.                     mov bx,offset ile_wejsciowych
  180.                     mov al,byte ptr ds:[bx]         ;sprawdzenie czy przerobiliśmy tą linię we wszystkich plikach?          
  181.                     cmp di,ax
  182.                     je write_a_new_line
  183.                     mov bx,offset bools_zrobione
  184.                     cmp byte ptr [bx+di],0  ;sprawdzenie czy skończyliśmy pracę z tym plikiem?
  185.                     je continue
  186.                     jne write_a_separator
  187.                     inc di          ;Jesli plik został przerobiony pomijam go i zaczynam dla kolejnego
  188.                     jmp for_in_files
  189.                    
  190.                     continue:       ;przepisywanie pojedynczej linii dla pliku
  191.                         mov si,di
  192.                         shl si,1    ;si mnożymy razy dwa bo word
  193.                         mov bx,offset bools_czy_pierwszy
  194.                         cmp byte ptr ds:[bx],1  ; czy wstawic separator
  195.                         jne write_a_separator
  196.                         mov byte ptr ds:[bx],0  ;nie wpisuje separatora na początku, a potem już tak
  197.                         jmp inner_loop
  198.                        
  199.                         write_a_separator:          ;nie jest to pierwszy znak więc wpisuje
  200.                             mov bx,offset bools_wyjsciowy
  201.                             cmp byte ptr ds:[bx],1  ;sprawdzam piszemy do pliku czy na konsole
  202.                             je file_separator
  203.                             call print_separator
  204.                             jmp inner_loop
  205.                             file_separator:
  206.                                 call file_put_separator
  207.                                
  208.                         inner_loop:
  209.                         call fread
  210.                         cmp cx,ax       ;Czy to koniec pliku?
  211.                         jne eof
  212.                         cmp byte ptr ds:[znak],13   ;Czy to znak nowej linii?
  213.                         je read_and_jump
  214.                         ;Albo wpisujemy nasz znak do pliku albo na konsole
  215.                         mov dx,offset znak  ;Na potrzeby procedur printf oraz fprintf
  216.                         mov bx,offset bools_wyjsciowy
  217.                         cmp byte ptr ds:[bx],1      ;do pliku czy na konsole?
  218.                         jne console_write
  219.                             call fprintf            ;Do pliku
  220.                             jmp inner_loop
  221.                            
  222.                         console_write:              ;Na konsole
  223.                             call printf
  224.                             jmp inner_loop
  225.                            
  226.                         read_and_jump:  ;Nowa linia więc zczytuje bit == 10
  227.                             call fread
  228.                             inc di  ;Zmieniam pliczek
  229.                             jmp for_in_files
  230.                            
  231.                         eof:                            ;Jesli napotkałem koniec pliku
  232.                             mov bx,offset bools_zrobione
  233.                             mov byte ptr ds:[bx+di],1   ;Zaznaczam że dany plik jest już przerobiony
  234.                             inc di
  235.                             jmp for_in_files
  236.                            
  237.                         write_a_new_line:
  238.                             mov bx,offset bools_czy_pierwszy    ;Nie drukuje ostatniej nowej linii
  239.                             cmp byte ptr ds:[bx],1
  240.                             je cmd_is_parsed
  241.                             mov bx,offset bools_wyjsciowy
  242.                             cmp byte ptr ds:[bx],1  ;Czy na konsole czy do pliku
  243.                             jne console_new_line
  244.                             call file_new_line      ;Do pliku
  245.                             jmp cmd_is_parsed
  246.                             console_new_line:       ;Na konsole
  247.                                 call print_new_line
  248.                                 jmp cmd_is_parsed
  249.        
  250.         ; PROCEDURY
  251.        
  252.         ;procedura wyswietlania pomocy - poprawnej skladni
  253.         wyswietl_pomoc:
  254.             cmp byte ptr es:[di+1],20h
  255.             ja throw_zla_skladnia
  256.             mov dx,offset pomoc
  257.             call printf
  258.             jmp exit
  259.            
  260.         ;procedura rzucająca blad
  261.         throw_exception:
  262.             mov dx,offset blad
  263.             call printf
  264.             jmp exit   
  265.            
  266.         ;procedura konczaca program, gdy pojawi sie blad skladniowy
  267.         throw_zla_skladnia:
  268.             mov dx,offset zla_skladnia
  269.             call printf
  270.             mov dx,offset pomoc
  271.             call printf
  272.             jmp exit
  273.            
  274.         ;procedura kończy program kiedy wybrano opcję -o a mimo tego nie podano nazwy pliku wyjściowego
  275.         throw_brak_o:
  276.             mov dx,offset brak_o
  277.             call printf
  278.             jmp exit
  279.            
  280.         ;procudura kończy program gdy wywołano opcję -o więcej niż jeden raz
  281.         throw_za_duzo_o:
  282.             mov dx,offset za_duzo_o
  283.             call printf
  284.             jmp exit
  285.            
  286.         ;procedura otwierająca plik wejsciowy/wyjsciowy
  287.         ;tryb otwierania znajduje się w al,a w si to co należy dodać do offsetu z bx
  288.         fopen:
  289.             mov ah,3dh          ;Otwieram plik do odczytu
  290.             int 21h             ;Otwieram plik
  291.             jc throw_problem_plik_wejsciowy
  292.             ;Udało nam się otworzyć plik więc należy zapisać uchwyt
  293.             mov ds:[bx+si],ax   ;Wpisujemy uchwyt otrzymany w ax,do ds:[bx+si]
  294.             ret
  295.            
  296.         ;procedura kończy program jeśli istnieje problem z odczytaniem/zapisaniem pliku
  297.         throw_problem_plik_wejsciowy:
  298.             mov dx,offset problem_plik_wejsciowy
  299.             call printf
  300.             jmp exit   
  301.            
  302.         ;procedura pobiera z pliku wejściowego o uchwycie ds:[pliki_wejsciowe_uchwyty + si] jeden znak
  303.         fread:
  304.             mov bx,offset pliki_wejsciowe_uchwyty
  305.             mov ax,ds:[bx+si]
  306.             mov bx,ax           ;W bx mam uchwyt do odpowiedniego pliku wejściowego
  307.             xor ax,ax
  308.             mov ah,3fh          ;Mówię procesorowi że czytam z pliku
  309.             mov cx,1            ;1 bajt danych == 1 znak
  310.             mov dx,offset znak  ;Zczytuje go do zmiennej znak
  311.             int 21h             ;W ax siedzi ilość pobranych znaków
  312.             jc throw_exception 
  313.             ret
  314.            
  315.         ;procedura wpisuje do pliku którego uchwyt jest w bx,jeden bajt z adresu ds:[znak]
  316.         fprintf:
  317.             mov bx,ds:[plik_wyjsciowy_uchwyt]   ;W bx przetrzymuje uchwyt do pliku
  318.             xor ax,ax
  319.             mov ah,40h
  320.             int 21h
  321.             jc throw_exception
  322.             ret
  323.            
  324.         ;procedura wpisuje do pliku separator
  325.         file_put_separator:
  326.             mov dx,offset separator
  327.             call fprintf
  328.             ret
  329.            
  330.         ;procedura wpisuje nową linię do pliku (rozmiar linii to 2 bajty)
  331.         file_new_line:
  332.             mov cx,2
  333.             mov dx,offset nwln
  334.             call fprintf
  335.             ret
  336.        
  337.         ;procedura zamyka plik wyjściowy, a następnie kończy program
  338.         fclose:            
  339.             mov bx,ds:[plik_wyjsciowy_uchwyt]       ;W bx przechowuje uchwyt zamykanego pliku
  340.             xor ax,ax
  341.             mov ah,3eh
  342.             int 21h
  343.             jmp exit
  344.            
  345.         ;procedura wypluwa separator na konsole
  346.         print_separator:
  347.             mov dx,offset separator
  348.             call printf
  349.             ret
  350.            
  351.         ;procedura wypluwa na konsole nowa linię
  352.         print_new_line:
  353.             mov dx,offset nwln
  354.             call printf
  355.             ret
  356.            
  357.         ;procedura wypisuje na ekran zawartość ds:dx
  358.         printf:
  359.             mov ah,9
  360.             int 21h
  361.             ret
  362.            
  363.         ;procedura, ktora konczy program
  364.         exit:
  365.             mov ah,04ch
  366.             int 21h
  367.     main endp
  368. code ends
  369. end start
Add Comment
Please, Sign In to add comment