; Program uruchamia inny program z podana data. ; Potem zamienia date na poprzednia ; ; Autor: Bogdan D. ; kontakt: bogdandr (at) op (dot) pl ; ; nasm -O999 -o data_f.com -f bin data_f.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 org 100h start: mov ax, cs mov ds, ax ; DS = CS mov dx, info mov ah, 9 int 21h ; wyswietl info o programie mov si, 80h ; SI -> ilosc znakow linii polecen mov al, [si] ; pobierz ta ilosc znakow or al, al ; i sprawdz, czy nie zero jnz ilosc_ok mov dx, sklad mov ah, 9 int 21h ; jesli zero, to wyswietl info o ; uzyciu programu mov ax, 4c01h int 21h ; wyjscie z kodem bledu 1 ilosc_ok: mov es, [ds:2ch] ; ES = segment zminnych srodowiskowych mov ah, 49h ; funkcja zwolnienia pamieci int 21h ; zwolnij srodowisko (.com) jnc free_ok ; czy wystapil blad? mov bx, ax ; zachowaj numer bledu w BX mov dx, blad_zw mov ah, 9 int 21h ; wypisz info o bledzie mov ax, bx call pl ; wypisz numer bledu mov dx, nwln mov ah, 9 int 21h ; przejdz do nowej linii free_ok: mov bx, cs mov es, bx ; ES = CS = segment, ktorego rozmiar ; chcemy zmienic mov bx, smieci ; BX = dlugosc naszego programu ;;; sub bx, start mov ah, 4ah ;funkcja zmiany rozmiaru bloku pamieci int 21h ; zostaw nam tylko tyle pamieci, ; ile trzeba na kod+dane jnc free_ok1 ; czy wystapil blad? mov bx, ax ; zachowaj numer bledu w BX mov dx, blad_zw mov ah, 9 int 21h ; wypisz info o bledzie mov ax, bx call pl ; wypisz numer bledu mov dx, nwln mov ah, 9 int 21h ; przejdz do nowej linii free_ok1: mov [kom_ln+2], cs ;uzupelniamy pola potrzebnych struktur mov [fcb1+2], cs mov [fcb2+2], cs mov ax, cs mov es, ax ; ES = CS ; ======================================================= ; teraz zajmiemy sie tym, co nam napisano w linii polecen petla: cmp si, 100h jnz ok1 ; sprawdzamy, czy jeszcze nie koniec ; linii polecen jmp kom_linia_juz ok1: inc si mov al, [si] ; pobieramy kolejny znak cmp al, 0dh ; sprawdzamy, czy nie Enter jnz ok2 jmp kom_linia_juz ok2: cmp al, ' ' jz petla ; pomijamy spacje ; ================ ; teraz nowa data ; najpierw numer dnia and al, 0fh ; AL = starsza cyfra numeru dnia mov ah, al mov cl, 3 shl ah, cl shl al, 1 add ah, al ; AH = AL*10 spcs1: ; tutaj pomijamy spacje cmp si, 100h ; ciagle sprawdzamy, czy juz nie ; koniec linii polecen jnz ok3 jmp kom_linia_juz ok3: inc si mov al, [si] ; pobierz kolejny znak cmp al, '0' ; sprawdzamy, czy cyfra. Jesli nie, ; to pomijamy znak jb spcs1 cmp al, '9' ja spcs1 and al, 0fh add ah, al ; AH = poprzednia cyfra*10 + nowa ; cyfra = numer dnia mov [dzien], ah ; ================ ; teraz numer miesiaca spcs2: ; tutaj tez pomijamy spacje cmp si, 100h ; ciagle sprawdzamy, czy juz nie ; koniec linii polecen jnz ok4 jmp kom_linia_juz ok4: inc si mov al, [si] ; pobierz kolejny znak cmp al, '0' ; sprawdzamy, czy cyfra. Jesli nie, ; to pomijamy znak jb spcs2 cmp al, '9' ja spcs2 and al, 0fh ; AL = wartosc cyfry mov ah, al shl ah, cl shl al, 1 add ah, al ; AH = wartosc cyfry*10 spcs3: ; tutaj tez pomijamy spacje cmp si, 100h ; ciagle sprawdzamy, czy juz nie ; koniec linii polecen jnz ok5 jmp kom_linia_juz ok5: inc si mov al, [si] ; pobierz kolejny znak cmp al, '0' ; sprawdzamy, czy cyfra. Jesli nie, ; to pomijamy znak jb spcs3 cmp al, '9' ja spcs3 and al, 0fh ; AL = wartosc cyfry add ah, al ; AH = poprzednia cyfra*10 + nowa ; cyfra = numer miesiaca mov [miesiac], ah ; ================ ; teraz numer roku spcs4: ; tutaj tez pomijamy spacje cmp si, 100h ; ciagle sprawdzamy, czy juz nie ; koniec linii polecen jnz ok6 jmp kom_linia_juz ok6: inc si mov al, [si] ; pobierz kolejny znak cmp al, '0' ; sprawdzamy, czy cyfra. Jesli nie, ; to pomijamy znak jb spcs4 cmp al, '9' ja spcs4 xor bx, bx and al, 0fh ; AL=wartosc cyfry=pierwsza cyfra roku mov bl, al shl bl, cl shl al, 1 add bl, al ; BL = AL*10 spcs5: ; tutaj tez pomijamy spacje cmp si, 100h ; ciagle sprawdzamy, czy juz nie ; koniec linii polecen jnz ok7 jmp kom_linia_juz ok7: inc si mov al, [si] ; pobierz kolejny znak cmp al, '0' ; sprawdzamy, czy cyfra. Jesli nie, ; to pomijamy znak jb spcs5 cmp al, '9' ja spcs5 and ax, 0fh ; celowo AX, aby wyzerowac AH. ;AL = druga cyfra roku add bx, ax mov dx, bx shl dx, cl shl bx, 1 add dx, bx ; DX = BX*10 spcs6: ; tutaj tez pomijamy spacje cmp si, 100h ; ciagle sprawdzamy, czy juz nie ; koniec linii polecen jnz ok8 jmp kom_linia_juz ok8: inc si mov al, [si] ; pobierz kolejny znak cmp al, '0' ; sprawdzamy, czy cyfra. Jesli nie, ; to pomijamy znak jb spcs6 cmp al, '9' ja spcs6 and al, 0fh ; AL=wartosc cyfry=trzecia cyfra roku add dx, ax ; do DX dodajemy nowa cyfre mov bx, dx ; BX = stara wartosc DX + nowa cyfra shl bx, cl shl dx, 1 add dx, bx ; DX = BX*10 spcs7: ; tutaj tez pomijamy spacje cmp si, 100h ; ciagle sprawdzamy, czy juz nie ; koniec linii polecen jnz ok9 jmp kom_linia_juz ok9: inc si mov al, [si] ; pobierz kolejny znak cmp al, '0' ; sprawdzamy, czy cyfra. Jesli nie, ; to pomijamy znak jb spcs7 cmp al, '9' ja spcs7 and al, 0fh ; AL=wartosc cyfry=czwarta cyfra roku add dx, ax ; dodajemy do roku ostatnia cyfre mov [rok], dx ; zapisujemy rok ; ==================== ; teraz nazwa programu spcs8: cmp si, 100h jz kom_linia_juz inc si mov al, [si] ; pobierz kolejny znak cmp al, 'A' ; sprawdzamy, czy litera. Jesli nie, ; to pomijamy znak jb spcs8 cmp al, 'z' ja spcs8 ; pozbywamy sie spacji z przodu mov di, program ; pod [DI] zapiszemy nazwe programu ; do uruchomienia spcs9: cmp si, 100h jz kom_linia_juz ; ciagle sprawdzamy, czy juz nie ; koniec linii polecen mov al, [si] ; drugi raz pierwszy znak inc si ; sprawdzamy, jaki znak wczytalismy. ; Jesli jakis ; dobry, to zapisujemy go pod [DI], ; jesli nie, to omijamy cmp al, ' ' jz prog_juz ; spacja oznacza koniec cmp al, '.' jz znak_ok cmp al, ':' jz znak_ok cmp al, '\' jz znak_ok cmp al, '0' jb spcs9 cmp al, '9' jb znak_ok cmp al, 'A' jb spcs9 cmp al, 'z' ja spcs9 cmp al, 'a' ja znak_ok cmp al,'Z' jb znak_ok znak_ok: mov [di],al ; trafilismy na dobry znak, wiec ; go zapisujemy cmp di, program + 80h ; sprawdzamy, czy nie przekroczylismy ; zmiennej 'program' jz prog_juz inc di jmp short spcs9 ; wczytujemy klejne znaki ; =================================== ; teraz wczytujemy linie polecen dla programu prog_juz: mov di, linia_kom + 1 ; bedziemy wczytywac pod [DI] mov byte [di], 20h ; zaczynamy od spacji inc di ; przechodzimy na kolejny znak petla2: cmp si, 100h ; ciagle sprawdzamy, czy juz nie ; koniec linii polecen jz kom_linia_juz mov al, [si] ; pobierz kolejny znak inc si cmp al, 0dh ; jesli to Enter, to koniec ; linii polecen jz kom_linia_juz mov [di], al ; zapisz ten znak w linii polecen ; uruchamianego prog. cmp di, linia_kom + 80h ; sprawdzamy, czy miescimy ; sie w zmiennej jz kom_linia_juz inc di jmp short petla2 ; sprawdz kolejny znak kom_linia_juz: sub di, linia_kom ; obliczamy dlugosc linii polecen mov ax, di mov [linia_kom], al ; i ta dlugosc zapisujemy na poczatku ; ( bo tak jest zawsze ) ; sprawdzamy, czy podane dane ; sa do przyjecia: cmp word [rok], 2079 ja zla_data cmp word [rok], 1980 jb zla_data cmp byte [miesiac], 12 ja zla_data cmp byte [miesiac], 1 jb zla_data cmp byte [dzien], 31 ; luty niewazny ja zla_data cmp byte [dzien], 1 jae ok_data zla_data: ; jesli cos jest nie tak z data, ; to wychodzimy mov dx, data_zla mov ah, 9 int 21h mov ax, 4c02h ; kod bledu: 2 int 21h ; sprawdzimy, czy nazwa programu ; spelnia zalozenia: ok_data: mov di, program mov cx, 80h mov al, '.' ; czy jest kropka? cld repne scasb jz prog_ok prog_nie_ok: ; jesli cos jest nie tak z nazwa ; programu, wychodzimy mov dx, zly_prog mov ah, 9 int 21h mov ax, 4c03h ; kod bledu: 3 int 21h prog_ok: cmp byte [di+1], 0 ; czy jest rozszerzenie? jz prog_nie_ok mov ah, 2ah ; pobieramy aktualna date i ; zapisujemy ja gdzies int 21h mov [stary_rok], cx mov [stary_mies], dh mov [stary_dzien], dl mov ah, 2bh ; ustawiamy nowa date mov cx, [rok] mov dh, [miesiac] mov dl, [dzien] int 21h or al, al ; sprawdzamy, czy wystapil jakis blad jz data_ustaw_ok cmp al, 0ffh jnz data_ustaw_ok mov dx, data_zla ; jesli wystapil blad, to wychodzimy mov ah, 9 int 21h mov ax, 4c02h ; kod bledu: 2 int 21h data_ustaw_ok: mov dx, nac_kl mov ah, 9 int 21h xor ah, ah int 16h call cls mov ax, cs mov ds, ax mov es, ax ; ES = DS = CS mov [sssp], sp ; zachowujemy nasz stos mov [sssp+2], ss mov ax, 4b00h ; funkcja uruchomienia programu mov dx, program mov bx, srod ; dla "uruchom" int 21h ; uruchamiamy ; =============================== ; uruchomiony prog. sie zakonczyl cli ; przywracamy nasz stos mov sp, [sssp] mov ss, [sssp+2] sti call cls mov di, 1 ; znacznik, ze cos poszlo nie tak jnc uru_ok ; sprawdzamy, czy uruchomienie ; sie powiodlo mov bx, ax ; jesli nie, to BX = kod bledu mov dx, uru_blad mov ah, 9 int 21h ; wyswietlamy info o bledzie ; mozliwe numery bledow: ; 1, 2, 5, 8, 0a, 0b mov ax, bx call pl ; wyswietlamy numer bledu mov dx, nwln mov ah, 9 int 21h ; przechodzimy do nowej linii ; ================================ ; teraz po kolei sprawdzamy, ktory blad wystapil ; i wypisujemy stosowna informacje cmp bl, 1 jnz nie1 mov dx, zly_fn mov ah, 9 int 21h jmp short bx_juz nie1: cmp bl, 2 jnz nie2 mov dx, brak_pliku mov ah, 9 int 21h jmp short bx_juz nie2: cmp bl, 5 jnz nie5 mov dx, acc_den mov ah, 9 int 21h jmp short bx_juz nie5: cmp bl, 8 jnz nie8 mov dx, brak_pam mov ah, 9 int 21h jmp short bx_juz nie8: cmp bl, 0ah jnz nie0a mov dx, zle_srod mov ah, 9 int 21h jmp short bx_juz nie0a: cmp bl, 0bh jnz bx_juz mov dx, zly_format mov ah, 9 int 21h bx_juz: xor di, di ; ============================ ; po prawidlowym uruchomieniu ; lub wypisaniu bledu: uru_ok: mov ax, cs mov ds, ax ; przywracamy DS = CS mov dx, nac_kl2 mov ah, 9 int 21h ; zaraz przywrocimy stara date xor ah, ah int 16h ; czekamy na klawisz mov ah, 2bh ; przywracamy stara date mov cx, [stary_rok] mov dh, [stary_mies] mov dl, [stary_dzien] int 21h or di, di ; sprawdzamy, czy byl problem z ; uruchomieniem jnz dalej mov ax, 4c04h ; jesli tak, to zwrocimy odpowiedni ; kod bledu int 21h dalej: ; jesli nie, to zwracamy kod bledu ; programu uruchomionego mov ah, 4dh int 21h ; kod zakonczenia or al, al jz zak_ok ; zero? to oznacza, ze uruchomiony ; program zakonczyl sie bez problemow mov bx, ax ; BX = kod bledu uruchomionego mov dx, prog_zak_blad mov ah, 9 int 21h ; info o bledzie programu uruch. mov ax, bx call pc2 ; wypisz zwrocony numer bledu mov dx,nwln mov ah,9 int 21h ; przejdz o 1 linie nizej mov ax,bx mov ah,4ch int 21h ; wychodzimy z takim samym kodem bledu, ; co uruchomiony przez nas program zak_ok: mov dx,prog_zak_ok mov ah,9 int 21h ; wszystko skonczylo sie dobrze mov ax,4c00h int 21h ; wychodzimy z kodem bledu: ; 0 (brak bledu) ; ------------------------ pl: ;we: ax - liczba ;wy: niszczone ax,bx,cl ; pisze liczbe szestnastkowo mov cl, 12 mov bx, ax shr ax, cl call pc2 ; wypisz najstarsze 4 bity (12-15) mov cl, 8 mov ax, bx shr ax, cl and al, 0fh call pc2 ; wypisz bity 8-11 mov ax, bx mov cl, 4 shr ax, cl and al, 0fh call pc2 ; wypisz bity 4-7 mov ax, bx and al, 0fh call pc2 ; wypisz najmlodsze 4 bity (0-3) ret ; ------------------------ pc2: ;we: AL - cyfra hex ;wy: pisze cyfre, niszczone ax cmp al, 9 ja hex or al, '0' jmp short PZ hex: add al, 'A'-10 PZ: mov ah, 0eh int 10h ret ; ------------------------ cls: ; czysci ekran pushf push ax mov ax, 0700h ; przewijanie ekranu mov bh, 7 ; atrybut xor cx, cx mov dx, 2479h int 10h ; to wyszysci caly ekran mov ah, 2 xor bh, bh xor dx, dx int 10h ; ustaw kursor w 0,0 pop ax popf ret ; ------------------------ rok dw 0 dzien db 0 miesiac db 0 stary_rok dw 0 stary_dzien db 0 stary_mies db 0 info db 'Program do zmiany daty podawanej innemu programowi.',10,13 db 'Autor: Bogdan D., bogdandr (at) op.pl, maj 2002',10,13,'$' sklad db 'Skladnia: data_f ' db ' ',10,13,'$' data_zla db 'Zla data.$' zly_prog db 'Zla nazwa programu.$' uru_blad db 'Blad uruchamiania programu. Kod: $' prog_zak_blad db 'Uruchomiony program zakonczyl sie z bledem. Kod: $' prog_zak_ok db 'Uruchomiony program zakonczyl sie bez bledow.$' nwln db 10,13,'$' zly_fn db 'Zly numer funkcji.$' brak_pliku db 'Nie znaleziono pliku.$' acc_den db 'Dostep zabroniony.$' brak_pam db 'Za malo pamieci.$' zle_srod db 'Zle srodowisko.$' zly_format db 'Zly format.$' ;psp dw 0 sssp dd 0 blad_zw db 10,13,'Blad przy zwlanianiu pamieci. Kod: $' nac_kl db 'Nacisnij klawisz, aby uruchomic program...',10,13,'$' nac_kl2 db 10,13,'Nacisnij klawisz, aby przywrocic stara date...',10,13,'$' linia_kom db 0 times 7fh db 0dh fcb db 3,' ',0,0,0,0,0 program times 81h db 0 srod dw 0 kom_ln dw linia_kom,0 fcb1 dw fcb,0 fcb2 dw fcb,0 smieci db 0