org 100h
;; Procedur zum lesen von TT.MM.YYYY (nasm)
%macro Lesen 0
push bp
mov bp,sp
sub sp,28h
cmp byte [80h],11 ; 80h = wie viel eingegeben ? TT.MM.YYYY + Leerzeichen = 11
je %%genug
%%fehler:
FEHLER ; prozedur FEHLER
%%genug:
mov si,82h ; 82h = beginn von den commandozeilen argumenten (81h=Leerzeichen)
xor bx,bx
inc bx
xor al,al
%%load:
lodsb ; al =zeichenladen
cmp bx,3
jb %%kleiner3
cmp bx,3
je %%punkt1
cmp bx,6
jb %%kleiner6
cmp bx,6
je %%punkt2
cmp bx,0Bh
je %%ente
mov di,bx ; bx ist ja der conter aber bp+bx ist falsch dafür bp+di ist richtig und ....
neg di ; man braucht bp-di
mov [bp+di],al
inc bx ; counter eins erhöhen ..
jmp %%load
%%kleiner3:
mov di,bx
neg di
mov [bp+di],al
inc bx
jmp %%load
%%punkt1:
%%punkt2:
cmp al,'.'
jne %%fehler
inc bx
jmp %%load
%%kleiner6:
mov di,bx
neg di
mov [bp+di],al
inc bx
jmp %%load
%%ente: ; ende ...
;; in BCD gepackt umwandeln
;; TT
xor ax,ax
mov al,byte [bp-1] ; al=erste Ziffer
cmp al,30h ;überprüfung ob es überhaupt eine ziffer ist
jb %%fehler
cmp al,39h
ja %%fehler
and al,0fh ; die ziffer ist im ascii format : ich wandele es in normale zahl um
shl al,4 ; die erste zahl ist ja die zehnerstelle also ....
mov ah,byte [bp-2] ; ist das gleiche bloß für die einerstelle
cmp ah,30h
jb %%fehler
cmp ah,39h
ja %%fehler
and ah,0fh
or al,ah ; al=Gepackte BCD Zahl zehner und einerstelle
;; MM ; hier passiert dass gleiche nur für Monat
xor bx,bx
mov bl,byte [bp-4]
cmp bl,30h
jb %%fehler
cmp bl,39h
ja %%fehler
and bl,0fh
shl bl,4
mov bh,byte [bp-5]
cmp bh,30h
jb %%fehler
cmp bh,39h
ja %%fehler
and bh,0fh
or bl,bh
mov ah,bl ; ah=Gepackte BCD Zahl zehner und einerstelle von monat
;; JJJJ ; das gleiche für das Jahr
xor bx,bx
mov bl,byte [bp-7]
cmp bl,30h
jb %%fehler
cmp bl,39h
ja %%fehler
and bl,0fh
shl bl,4
mov bh,byte [bp-8]
cmp bh,30h
jb %%fehler
cmp bh,39h
ja %%fehler
and bh,0fh
or bl,bh
mov dh,bl
xor bx,bx
mov bl,byte [bp-9]
cmp bl,30h
jb %%fehler
cmp bl,39h
ja %%fehler
and bl,0fh
shl bl,4
mov bh,byte [bp-10]
cmp bh,30h
jb %%fehler
cmp bh,39h
ja %%fehler
and bh,0fh
or bl,bh
mov dl,bl ; hier ist das für das Jahr zuende und dann steht in dh GBCD huderter und in dl GBCD einer/zehner
mov sp,bp
pop bp
%endmacro
;; ENDE der Procedur
;; Procedur zum überprüfen ob TT<=31 und MM<=12 (Jahr ist sowiso richtig ...)
%macro Uberprufen 0 ; ich denker die prozedur ist selbsterklärend ....
push bp
mov bp,sp
sub sp,28h
cmp al,00110001b ; 31
ja %%fehler
cmp ah,00010010b ; 12
ja %%fehler
jmp %%nee
%%fehler:
FEHLER
%%nee:
mov sp,bp
pop bp
%endmacro
;; ENDE der Procedur
;; Procedur zum ausrechnen des Unterschiedes
%macro Rechnen 0
mov cl,dl ; dl (zehner einer des Jahres) nach cl
teilbar ; überprüft ob durch 4 teilbar und setet carry wenn ja und ansonsten clear carry
jc %%nuller ; wenn durch 4 teilbar
%%normal:
xor bx,bx ; da wird ergebnis gespeichert
%%schalti:
dec al ; tag um eins verkürzen (der unterschied ist ja zwischen TT und 01 und nicht 00)
mov cl,al ; al ist eine gepackte bcd zahl ...
and al,0F0h ; in al steht jetzt die zehner ..
shr al,4 ;werden zu einern gemacht also als beispiel : wird 50 zu 5 ; da ich es nach binär umwandeln muss
mov ch,al ; zehner nach ch absichern
add al,al ; al*10 ...
add al,al
add al,al
add ch,ch
add al,ch ; ...
add bl,al ; in bl steht ja dann das ergebniss drin
and cl,0Fh ; in cl jetzt einer
add bl,cl ; ...
mov ch,ah ; Monat ... gebackte BCD ...
and ah,0Fh
and ch,0F0h
shr ch,4
mov cl,ch ; ch*10 ...
add ch,ch
add ch,ch
add ch,ch
add cl,cl
add ch,cl ; ...
add ah,ch
movsx di,ah
add di,di
add bx,word [TABELLE+di] ; ... monat ...
jmp %%ente
%%nuller:
test dl,dl ;durch huntert teilbar ?
je %%hundert
cmp ah,3 ; wenn der monat kleiner ist als 3 dann ist es egal ob schaltjahr oder nicht
jb %%nee1
xor bx,bx ; wenn schaltjahr dann bx auf 1 setzten = wenn schaltjahr um eins erhöhen
inc bx
jmp %%schalti
%%nee1:
jmp %%normal
%%hundert: ; wenn durch hundert teilbar muss überprüft werden ob durch 400 teilbar wenn ja = SChaltjahr wenn nein = kein schaltjahr
mov cl,dh ; dh nach cl (dh = GBCD Hunderter da ich nur überprüfen brauche ob die hunderter durch 4 teilbar sind)
teilbar ; ...
jnc %%nichtschalt
cmp ah,3
jb %%nee1
xor bx,bx
inc bx
jmp %%schalti
%%nichtschalt:
jmp %%normal
%%ente:
%endmacro
;; ENDE der Procedur
;; Prozedur zum Ausgeben des Ergebnisses
%macro Ausgeben 0
mov ax,bx ; in ax jetzt dass ergebniss
mov cx,000ah ; mann muss immer wieder durch 10 (=0ah) teilen
xor bx,bx
xor dx,dx ; ohne gibts probleme ...
%%weita:
div cx ; in ax steht jetzt dass ergebniss und in dx der rest also beispiel: 35/10 = ax=3 dx=5
push dx ; wird alles hochgepusht dann wieder runter gepopt und später ausgegeben
xor dx,dx ; ..
inc bl ; zähler...
test ax,ax ; ergebnis 0 ?
je %%fertig ; dann aufhöhren
jmp %%weita ; ansonsten weitermachen
%%fertig:
mov dx,unterschied ; ...
mov ah,09
int 21h ; ausgeben
mov ah,02 ; um ascii zeichen in dx auszugeben
%%inter:
pop dx ; hohle letzte berechnete ziffer ...
add dx,30h ; um in ascii umzuwandeln
int 21h ; ausgeben
dec bl ; zähler eins weniger
test bl,bl
je %%jea ; wenn zähler 0 dann fertig
jmp %%inter ; ansonsten weiter
%%jea:
%endmacro
;; ENDE der Prozedur
;; Prozedur für Fehler
%macro FEHLER 0 ; wenn ein fehler passiert .......
mov dx,fehl
mov ah,09
int 21h
mov ax,4c00h
int 21h
%endmacro
;; ENDE der Prozedur
;; Prozedur um festzustellen ob eine BCD Zahl durch 4 teilbar ist mit cl = gepackte BCD zahl ch wird für temporäre zwecke benutzt
%macro teilbar 0
mov ch,cl
and cl,0Fh
and ch,0F0h
shr ch,4
add ch,ch
add cl,ch
add ch,ch
add ch,ch
add cl,ch
shl cl,6
test cl,cl
je %%ja
clc
jmp %%ne
%%ja:
stc
%%ne:
%endmacro
;; ENDE der Prozedur
;; Programm zum berechnen von TT.MM.YYYY undzwar der unterschied zwischen 01.01.YYYY und TT.MM.YYYY
Lesen ; lesen von TT.MM.YYYY
Uberprufen ; stimmt die eingabe ?
Rechnen ; rechne unterschied aus
Ausgeben ; gib das ergebniss aus
mov ax,4c00h ; Ende
int 21h
fehl db 0dh,0ah,"Hilfe:",0dh,0ah,"Geben sie den namen dieses Programms gefolgt von ",0dh,0ah
db "einem LEERZEICHEN UND eines Datums z.B. :",0dh,0ah
db "unter.com 25.11.1922",0dh,0ah
db "die Syntax ist dabei immer TT.MM.JJJJ",0dh,0ah
db "TT= Tag z.B. 05 MM= Monat z.B. 08 JJJJ= Jahr z.B. 1520",0dh,0ah,'$'
unterschied db "Der Unterschied in Tagen, zum 01.01 der Jahres, ist ",'$'
TABELLE: ; tabelle für monate ...
dw 0
dw 0
dw 31
dw 59
dw 90
dw 120
dw 151
dw 181
dw 212
dw 243
dw 273
dw 304
dw 334