; Program do zamiany wzoru na Odwrotna Notacje Polska ; ; Autor: Bogdan D. ; kontakt: bogdandr (malpka) op (kropka ) pl ; ; kompilacja: ; nasm -O999 -w+orphan-labels -o onp.com -f bin onp.asm ; ; Copyright (C) 2005-2007 Bogdan 'bogdro' Drozdowski, bogdandr @ op . pl ; ; Ten program jest wolnym oprogramowaniem; mozesz go rozpowszechniac ; i/lub modyfikowac zgodnie z licencja GNU Lesser General Public License ; (GNU LGPL) w wersji wydanej przez Fundacje Wolnego Oprogramowania; ; wedlug wersji 3 Licencji lub (jesli wolisz) jednej z pozniejszych wersji. ; ; Ten program jest udostepniany z nadzieja, ze bedzie uzyteczny, lecz ; BEZ JAKIEJKOLWIEK GWARANCJI; nawet domyslnej gwarancji PRZYDATNOSCI ; HANDLOWEJ albo PRZYDATNOSCI DO OKRESLONYCH ZASTOSOWAN. W celu uzyskania ; blizszych informacji - Licencja GNU Lesser General Public License. ; ; Z pewnoscia wraz z niniejszym programem otrzymales tez egzemplarz ; Licencji GNU Lesser General Public License; jesli nie - napisz do ; Fundacji Wolnego Oprogramowania: ; Free Software Foundation ; 51 Franklin Street, Fifth Floor ; Boston, MA 02110-1301 ; USA %idefine bksp 8 ; definicje kilku znakow %idefine tab 9 %idefine lf 10 %idefine cr 13 %idefine spc ' ' %idefine escp 27 org 100h ; program typu .com mov ax, cs mov si, 80h ; SI -> ilosc znakow linii polecen mov ds, ax ; DS = CS mov es, ax ; ES = CS mov bl, [si] ; BL = liczba znakow w linii polecen inc si ; SI -> pierwszy znak w linii polecen ; (spacja) mov ah, 9 mov dx, info int 21h ; wypisz info cmp bl, 2 ; liczba znakow > 2 => podano ; linie polecen jb bez_arg inc si ; 2. raz, SI-> pierwszy znak jmp z_arg ; ==================================== bez_arg: xor di, di mov dx, podaj mov ah, 9 int 21h ; wyswietlamy prosbe o ; wpisanie wyrazenia petla: xor ah, ah int 16h ; pobieramy znaki mov ah, 0eh cmp al, escp jne znak_dalej jmp koniec ; jesli wcisnieto Esc, wychodzimy. znak_dalej: cmp al, cr je input_juz ; Enter oznacza koniec wpisywania cmp al, bksp je jest_bksp ; gdy nacisnieto BackSpace int 10h ; wyswietl wprowadzony znak mov [wejscie+di], al ; zapisujemy znak do ; lancucha wejsciowego cmp di, 0ffh jz input_juz ; sprawdzamy, czy nie ; koniec lancucha inc di jmp short petla jest_bksp: ; gdy naciśnięto BkSp or di, di jz petla ; wracamy, jesli nie ma nic ; do usuniecia dec di ; kasujemy ostatni znak int 10h mov al, spc int 10h mov al, bksp int 10h jmp short petla ; ==================================== input_juz: mov si, -1 ; indeks do lancucha wejsciowego xor di, di ; indeks do lancucha wyjsciowego xor bx, bx ; indeks do stosu przetwarzaj: xor ax, ax ; wyzeruj biezacy znak AL i ; priorytet AH inc si ; przejdz do kolejnego znaku mov al, [wejscie+si] ; pobierz znak ; pomijamy białe znaki cmp al, spc je przetwarzaj cmp al, tab je przetwarzaj test al, al jz koniec_przetw ; wychodzimy na bajcie zerowym ; ----------------------- cmp al, '0' ; jesli cyfra/zmienna, to przepisz ; do "wyj" jb niecyfra cmp al, '9' ja niecyfra mov [wyj + di], al ; zapisz do lancucha wyjsciowego inc di ; DI wskazuje na kolejne wolne miejsce mov byte [byla_zmienna], 1 jmp short przetwarzaj ; ----------------------- niecyfra: ; sprawdzmy, czy litera cmp al, 'A' jb nielitera cmp al, 'Z' ja spr_male mov [wyj + di], al inc di mov byte [byla_zmienna], 1 jmp short przetwarzaj spr_male: cmp al, 'a' jb nielitera cmp al, 'z' ja nielitera mov [wyj + di], al inc di mov byte [byla_zmienna], 1 jmp short przetwarzaj ; ----------------------- nielitera: cmp byte [byla_zmienna], 1 jne bez_spacji mov byte [wyj + di], spc inc edi mov byte [byla_zmienna], 0 bez_spacji: cmp al, '(' ; jesli nawias (, to na stos jne nie_nawias_l mov [stosik+bx], ax ; wpisz na stos add bx, 2 ; BX pokazuje na kolejne wolne miejsce jmp short przetwarzaj nie_nawias_l: ; operator dzialania ; priorytety: {'(', 0)}, {'+','-',')', 1} ; {'*','/', 2}, { '^', 3 } cmp al, '+' jne nie_plus mov ah, 1 ; priorytet jmp short prior_juz nie_plus: cmp al, '-' jne nie_minus mov ah, 1 ; priorytet jmp short prior_juz nie_minus: cmp al, ')' jne nie_nawias_p ; jeśli nawias ")", to przepisz ze ; stosu wszystko do "(" wlacznie .przepisuj: test bx, bx jz zly_token ; sprawdz, czy nie koniec stosu sub bx, 2 ; przejdz na poprzednia wartosc na stosie mov cl, [stosik+bx] cmp cl, '(' je short .juz ; konczymy przepisywanie, gdy trafimy ; na '(' mov [wyj+di], cl ; przepisz do lancucha wyjsciowego inc di jmp short .przepisuj .juz: ; mov ah, 1 ; priorytet ; jmp short prior_juz jmp przetwarzaj nie_nawias_p: cmp al, '*' jne nie_mnoz mov ah, 2 ; priorytet jmp short prior_juz nie_mnoz: cmp al, '/' jne nie_dziel mov ah, 2 ; priorytet jmp short prior_juz nie_dziel: cmp al, '^' jne zly_token mov ah, 3 ; priorytet ; jmp short prior_juz prior_juz: ; jesli stos pusty, wpisz na ; wierzch stosu test bx, bx jnz .testuj_inne mov [bx+stosik], ax add bx, 2 jmp przetwarzaj .testuj_inne: cmp [stosik+bx-1], ah ; porownujemy priorytet biezacego ; operatora z tym na stosie ; jesli priorytet operatora na stosie ; jest mniejszy, wpisz na wierzch stosu jae .zdejmuj mov [bx+stosik], ax add bx, 2 jmp przetwarzaj .zdejmuj: test bx, bx jz zly_token ; sprawdz, czy stos nie jest pusty sub bx, 2 ; zdejmujemy ze stosu wszystkie ; operatory o wiekszym lub ; rownym priorytecie mov cl, [bx+stosik] ; pobierz znak ze stosu mov [wyj+di], cl ; zapisz do lancucha wyjsciowego inc di cmp [stosik+bx-1], ah ; znowu porownaj priorytet jae .zdejmuj ; i dalej zdejmuj, jesli trzeba mov [bx+stosik], ax ; a biezacy znak dopisz na stos add bx, 2 jmp przetwarzaj zly_token: mov [zly_znak], al mov ah, 9 mov dx, zly int 21h ; wypisz info o zlym znaku jmp short koniec ; ----------------------- koniec_przetw: test bx, bx jz juz ; sprawdz, czy stos nie jest pusty sub bx, 2 ;przejdz na wczesniejszy znak ze stosu ; przepisz stos do wyjscia mov al, [stosik+bx] mov [wyj+di], al inc di ; DI wskazuje na kolejne miejsce na ; kolejny znak jmp short koniec_przetw juz: mov ah, 9 mov dx, wynik int 21h ; wyswietl wynik ; ==================================== koniec: mov ax, 4c00h int 21h ; ==================================== z_arg: ; pobranie argumentow z linii polecen ; SI = 82h -> pierwszy znak xor di, di wej: mov al, [si] cmp si, 100h je wej_juz cmp al, cr ; sprawdzamy, czy nie koniec linii je wej_juz cmp al, lf je wej_juz ; pomijamy biale znaki cmp al, ' ' je omin cmp al, tab je omin mov [wejscie+di], al inc di omin: inc si jmp short wej wej_juz: jmp input_juz ; ==================================== info db 'Program zamienia wyrazenie na Odwrotna Notacje Polska.',cr,lf,'$' podaj db 'Podaj wyrazenie: $' zly db cr, lf, 'Nieprawidlowy token: ' ; celowo bez '$' zly_znak db ' $' wynik db cr, lf, 'Wynik: ' ; celowo bez '$' wyj times 100h db '$' wejscie times 100h db 0 stosik times 200h db 0 byla_zmienna db 0