Home |
8086 Assembler,
|
Zurück zur Assemblerauswahlseite |
Unter MSDOS bewegt man sich mit dem Befehl „CD“ durch die Verzeichnisse. Das hier gezeigte Programm „GO“ erleichtert die dabei anfallende Tipparbeit. Dazu enthält es einige Ziele des Verzeichnisbaumes. Wird es ohne
Parameter aufgerufen, zeigt es die ihm unterstützten Ziele (siehe blauen Kasten unterhalb). Tippt man jedoch „go etc“, findet man sich im Verzeichnis C:\WINDOWS\SYSTEM32\DRIVERS\ETC wieder.
D:\dos\ML\Test>go Usage: GO pfad Als pfad wird ein Pfadname, Teile eines Pfadnamens,/ oder \ oder .. erwartet. Die aktuell auf der Platte vorhandene Directory-Struktur laesst sich mit tree /A >datei.txt speichern. Directories: D:\DATEN D:\DATEN\123 D:\DATEN\ADMI D:\DATEN\WORD D:\DOS D:\4DOS D:\TEMP D:\TEMP\FREDDY-DATEIEN C:\WINDOWS C:\WINDOWS\SYSTEM32 C:\WINDOWS\SYSTEM32\DRIVERS\ETC D:\TEMP\ASM\HOMEPAGE NEW D:\HOMEPAGE D:\HOMEPAGE\NETCUP\HTML D:\DOS\MASM D:\DOS\ML\TEST D:\DOS\ML\QUELLEN D:\DOS\NU D:\DOS\Q D:\DOS\QB45 D:\DOS\QB45\BEISPIEL D:\DOS\QB45\RATG_BSP D:\DOS\TURBOC D:\DOS\TURBOC\INCLUDE D:\DOS\TURBOC\LIB D:\INSTALL D:\GI D:\dos\ML\Test> Die Funktionsweise wird anhand einiger Beispiel deutlich:<<ul>
Obwohl das Programm die Routinensammlung firm.mac verwendet, besitzt es eine eigene Routine zur Wandlung des eingetippten Parameters in Großschrift. Die Indexregisterbenutzung bei dem entsprechenden Unterprogramm in firm.mac war hier unpassend. Die ab dem Merkmal „names“ definierte Tabelle der unterstützten Verzeichnisse muss individuell aufgebaut werden. Das aufgelistete Programm verarbeitet lange Verzeichnisnamen. Diese dürfen auch Zwischenräume (blanks) enthalten.
.MODEL TINY
title go fuer HP-Laptop
page 65,120
comment #
zur schnellen Anwahl von Directories
Matthaei, 12.11.90, 27.12.93, 26.10.200
23.1.2011 angepasst fuer ML
12.2.2011 lange Directorynamen und Suchfunktion erweitert
#
title entab
page 65,120
false equ 0
true equ not false
dump$ equ false ;fuer mdump, rdump
prompt$ equ false ;fuer enter, inkjn
intasc$ equ false ;fuer int2asc, asc2int
string$ equ true ;fuer fill, cmpstr, lenstr, instrg, movstr, ucaseg, lcaseg
.CODE
org 100h
_start: jmp around
include firm.mac
;Arbeitsfelder
wlparm dw 0 ;Nettoparameterlaenge
wparm dw 0 ;Startadr (Offset) des Parameters
wlname dw 0 ;Laenge des Eintrages in Namenstabelle
wname dw 0 ;Startadresse (Offset) des Eintrages in Namenstabelle
curdir db 130 dup ('0') ;Zwischenspeicher Name des aktuellen Verzeichnisses
spaces15 db ' ',0 ;15 Spaces zur Anzeige
;Besondere Directories
home db '\',0 ;Grundbibliothek
back db '..',0 ;eine Stufe zurück
;Tabelle der Directorynamen
;Bitte alles in Grossschrift!!!
names:
dbz "D:\DATEN"
dbz "D:\DATEN\123"
dbz "D:\DATEN\ADMI"
dbz "D:\DATEN\WORD"
dbz "D:\DOS"
dbz "D:\4DOS"
dbz "D:\TEMP"
dbz "D:\TEMP\FREDDY-DATEIEN"
dbz "C:\WINDOWS"
dbz "C:\WINDOWS\SYSTEM32"
dbz "C:\WINDOWS\SYSTEM32\DRIVERS\ETC"
dbz "D:\TEMP\ASM\HOMEPAGE NEW"
dbz "D:\HOMEPAGE"
dbz "D:\HOMEPAGE\NETCUP\HTML"
dbz "D:\DOS\MASM"
dbz "D:\DOS\ML\TEST"
dbz "D:\DOS\ML\QUELLEN"
dbz "D:\DOS\NU"
dbz "D:\DOS\Q"
dbz "D:\DOS\QB45"
dbz "D:\DOS\QB45\BEISPIEL"
dbz "D:\DOS\QB45\RATG_BSP"
dbz "D:\DOS\TURBOC"
dbz "D:\DOS\TURBOC\INCLUDE"
dbz "D:\DOS\TURBOC\LIB"
dbz "D:\INSTALL"
dbz "D:\GI"
db 0
;-------
;Upros
;-------
;------
;rcut ermittelt das Ende des Tokens anhand der Separatoren
;CR oder 00. Die Stringlaenge wird in CX zurückgegeben.
;Eingabeparameter: bx=Stringadresse
;------
rcut: xor cx,cx
push bx ;der String wird über bx adressiert
push dx
mov dx,0d00h ;Separaroren cr und 00
rcut5: cmp b[bx],dl
jz rcut9
cmp b[bx],dh
jz rcut9
inc bx
inc cx
jmps rcut5
rcut9: pop dx
pop bx
ret
;-------
;caseg string case conversions (german)
;Eingabeparameter: bx=Stringadresse, cx=Stringlaenge
;-------
Ucaseg1:
or cx,cx
jz luraus1 ;falls Leerstring
push bx ;der String wird ueber bx adressiert
push cx
push dx
mov dx,6120h ;DH = 'a', DL = conversion factor
convupper:
mov al,[bx]
cmp al,'/'
jne bu
mov [bx],b '\'
jmps luraus
bu: cmp al,dh
jb lu
cmp al,'z'
ja lu
sub al,dl
mov [bx],al
jmps luraus
lu: cmp al,'ä'
jne luoe
mov [bx],b 'Ä' ;Ae
jmps luraus
luoe: cmp al,'ö'
jne luue
mov [bx],b 'Ö' ;Oe
jmps luraus
luue: cmp al,'ü'
jne luraus
mov [bx],b 'Ü' ;Ue
luraus: inc bx
loop convupper
pop dx
pop cx
pop bx
luraus1: ret
;-------
;fbksl sucht im Token den naechsten ;Eingabeparameter: bx=Stringadresse
;Ausgabeparameter: bx=letzte Suchstelle
;Stringende: 0
;-------
fbksl: cmp b[bx],0
je fbksl9
cmp b[bx],'\'
je fbksl9
inc bx
jmps fbksl
fbksl9: ret
;-------
;Fortsetzung des Hauptpropgramms
;-------
around:
mov si,lparm ;Laenge des Parameters
xor ch,ch
mov cl,[si]
or cx,cx
jne start2
jmp hilfe ;Ausstieg, wenn keine Parameterangabe
start2: inc si ;ueüberlesen fueührende Spaces
cmp b[si],' '
jne start3
loop start2
;falls nur \ oder / eingegeben wurde, dann ins Grundverzeichnis
start3: cmp b[si],'\'
je start4
cmp b[si],'/'
jne start5
start4: cmp cx,1
jne start7
lea dx,home ;CD mit \ auf Grunddirectory
jmp chg_dir
;falls nur .. eingegeben wurde, dann ins uebergeordnete Verzeichnis
start5: cmp b[si],'.'
jne start10
inc si
cmp b[si],'.'
jne start10
dec si
cmp cx,2
jne start10
lea dx,back ;CD mit .. eine Stufe zurueück
jmp chg_dir
;falls die Eingabe mit einem \ ode / beginnt, wird der \ oder / ignoriert
start7: inc si
dec cx
start10:
mov bx,si ;eingegebenen Parameter konditionieren,
call rcut ;d.h., Laenge feststellen
mov w wlparm,cx ;Nettolaenge des Parameters
call ucaseg1 ;und in Grossschrift sowie / in \ wandeln
mov w wparm,si ;Startadresse des Parameters
add si,wlparm
mov b [si],0 ;eingegebenen Parameter mit 0 terminieren
;Hier beginnen die Vergleiche des Parameters
;1. Beste Aehnlichkeit versuchen: Parameter und Dirname voll identisch ?
lea di,names ;Adresse der gespeicherten Directorynamen
mov bx,di
start12:
call rcut ;cx enthaelt Laenge des Namenseintrages
or cx,cx
jnz start13
jmp start20 ;Namenstabelle ist abgearbeitet
start13:
cmp cx,w wlparm
push cx
jnz start18 ;verschieden lang
start15: ;cx=Laenge
mov si,bx ;Adr. Eintrag in Namenstabelle
mov di,w wparm ;Adresse Parameter
cld ;Richtung aufwaerts
repe cmpsb
jnz start18 ;verschieden
mov di,bx ;Eintrag in Namenstabelle fuer CD
mov dx,di
jmp chg_drv ;CD mit passendem Namenseintrag
start18: pop cx
add bx,cx ;also verschieden, dann
inc bx ;naechsten Namenseintrag aufsuchen
jmps start12
start20:
;2. Naechstbeste Aehnlichkeit versuchen: Parameter beginnt linksbüuendig
; auf einem DIR- oder SubDIR- Namen
; Der Vergleich erfolgt in der Laenge des Parameters
mov bx,offset names ;Adresse der gespeicherten Directorynamen
start22:
mov w wname,bx ;Adresse der Namenseintrages
call rcut ;cx enthaelt Laenge des Namenseintrages
mov w wlname,cx
start23:
call rcut ;cx enthaelt Laenge des Namenseintrages
or cx,cx
jnz start24
jmp start50 ;wenn Namenstabelle ohne Verzeichniswechsel
;abgearbeitet ist
start24:
cmp cx,w wlparm
jl start38 ;Parameter ist laenger als Namenseintrag
start25:
mov cx,w wlparm
mov si,bx ;Adr. Eintrag in Namenstabelle
mov di,w wparm ;Adresse Parameter
cld ;Richtung aufwaerts
repe cmpsb
jnz start30 ;verschieden
mov di,w wname ;Eintrag in Namenstabelle fuer CD
mov dx,di
jmp chg_drv ;CD mit passendem Namenseintrag
start30: call fbksl ;suchen, ob ein \ im Namenseintrag ist
cmp b[bx],'\'
jne start38 ;kein \ gefunden
inc bx ;auf Namensanfang
jmp start23
start38:
mov cx,w wlname
mov bx,w wname
add bx,cx ;naechsten Namenseintrag
inc bx
jmp start22
start50:
;3. Naechstsbeste Aehnlichkeit versuchen: Parameter beginnt irgendwo
; innerhalb eines Namenseintrags.
; Der Vergleich erfolgt in der Laenge des Parameters
mov bx,offset names ;Adresse der gespeicherten Directorynamen
start52:
mov w wname,bx ;Adresse der Namenseintrages
call rcut ;cx enthaelt Laenge des Namenseintrages
mov w wlname,cx
start53:
call rcut ;cx enthaelt Laenge des Namenseintrages
or cx,cx
jnz start54
jmp ret0 ;wenn Namenstabelle ohne Verzeichniswechsel
;abgearbeitet ist
start54:
cmp cx,w wlparm
jl start68 ;Parameter ist laenger als Namenseintrag
start55:
mov di,w wname ;Adr. Eintrag in Namenstabelle
mov si,w wparm ;Adresse Parameter
call instrg ;ist der Parmeter entgalten?
jz start68 ;nein. Dann naechster Namenseintrag
mov di,w wname ;Eintrag in Namenstabelle fuer CD
mov dx,di
jmp chg_drv ;CD mit passendem Namenseintrag
start68:
mov cx,w wlname
mov bx,w wname
add bx,cx ;naechsten Namenseintrag
inc bx
jmp start52
;Drive und Verzeichnis wechseln
;CALL interrupt(H21, inreg, outreg)
chg_drv:
push dx
mov dl,[di] ;Drive Buchstabe
and dl,1fh ;make binary
sub dl,1
mov ah,0eh ;Funktion select drive
int dos
pop dx
chg_dir:
; mov ah,3bh ;Funktion Change Directory
stc
mov ax,713bh ;Funktion change Directory
int dos
mov si,offset curdir
xor dl,dl ;aktuelles Laufwerk
stc
mov ax,7147h ;get current directory
int dos
mov si,offset curdir ;Anzeige aktuellen Pfad
call printa ;bei Programmende
jmp ret0
;Hilfstextanzeige wenn Aufruf ohne Parameter, nur Spaces als Parameter
hilfe: call prmsg ;zusaetzlicher Hinweistext
dbl 'Usage: GO pfad'
db 'Als pfad wird ein Pfadname, Teile eines Pfadnamens,'
dbl '/ oder \ oder .. erwartet.'
db 'Die aktuell auf der Platte vorhandene Directory-Struktur'
dbl ' laesst sich mit'
db 'tree /A ',3eh;'
dbl 'datei.txt'
dbl 'speichern.'
db cr
dbl "Directories:"
db 0
lea si,names ;Anzeige der gespeicherten Directorynamen
hilfe1: call printa ;Anzeige eines Namens
cmp b[si],0 ;Tabelle abgearbeitet ?
jnz hilfe2 ;nein
jmp hilfe5 ;Programmende
hilfe2: mov ah,3 ;Cursorposition bestimmen, um Abstand
xor bh,bh ;zum naechsten Directorynamen zu erzeugen
int 10h
cmp dl,48 ;Zeilenende?
jle hilfe3 ;nein
print_crlf ;ja: CR und naechsten Directorynamen anzeigen
jmps hilfe1
hilfe3: push dx
print_chr ' ' ;1 Space ausgeben
pop dx
inc dl ;wegen des Spaces
and dl,0fh ;Tabulator auf 16
push si ;passende Anzahl Spaces ausgeben
lea si,spaces15
xor dh,dh
add si,dx
call printa ;Ausgabe Spaces
pop si
jmps hilfe1
hilfe5: jmp ret1 ;Errorlevel 1 zurüueckgeben da Parameterfehler
end _start
|