?? pathanal.asm
字號:
;/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; This file will process the whole pathes at one time (batch
; processing) when one transaction has been finished, it will
; ajust the dirp points to the next transaction. the parambuf
; store all the pathes to the Minix files, each path starts
; with '/', end with '$', makes it easy to be recognized by
; eatpath subroutine, the paramnr indicates the number of
; characters remain, the whole subroutine will be terminated
; after it detects paramnr has reached to 0, the eatpath won't
; return until it finished analysising all the path and complete
; all the I/O.
;
; The entry points into this file are
; nextchar: get character indicate by dirp pointer
; eatpath: scale down verion of UNIX namei(), no paramter
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
include const.inc
include comstruc.inc
sseg segment stack
db 128 dup (0)
sseg ends
overlap segment para common 'strucinfo'
; this is the only way to reference
; extern struct
inodeinfo minixinode <>
superinfo minixsuper <>
dent dirent <>
overlap ends
dseg segment para public 'global'
public fulstr
extrn prom:byte
extrn dbuf:byte
extrn zonespace:byte
extrn dirp:word ; path charcter indicator
extrn parambuf:byte
extrn paramnr:byte
extrn fn:word ; files have been processed
extrn newline:byte ; line return
fulstr equ this byte
fulpath db 126 dup (0) ; display buf
db '$' ; protect run out
swtch db 0 ; switch off
startp dw 0 ; display buf pointer
illegmes db 'illegal path component encounted %s','$'
sucessmes db 'loading %s ... ','$'
errpath db 'error path component %s','$'
;debug
entrynr db '%d entries left','$'
dseg ends
cseg segment para public 'code'
assume cs:cseg,ds:dseg,es:dseg,ss:sseg
public nextchar,eatpath
extrn printf:near
extrn getinode:near
extrn getzone:near
extrn bmap:near
extrn wrtfile:near
;/============================================================================
;
; nextchar
;
;============================================================================/
nextchar proc near
push si
push di
push ds
push es
push bp
mov bp,sp
mov si,[dirp] ; dirp was initiated by eatpath
xor ax,ax
mov al,[si] ; fetch character to al
inc word ptr [dirp] ; *dirp++
; we can't use ax any more because it
; already contain the return value
dec word ptr [paramnr] ; first side effect
; startp was initiate by eatpath
cmp word ptr [swtch],0
je noeffect ; second side effect was controlled by swtch
mov di,[dirp]
dec di ; synchronous with nextchar subroutine
mov si,[di]
mov di,[startp]
mov [di],si
inc word ptr [startp] ; *startp++ = *[dir-1]++
; if path analysis failed in the inner component, it is
; the caller's responsibility to move back one char
; of startp pointer finally add '$' at tail
noeffect:
mov sp,bp
pop bp
pop es
pop ds
pop di
pop si
ret
nextchar endp
;/============================================================================
;
; eatpath
;
;============================================================================/
eatpath proc near
push ds
push es
push bp
mov bp,sp
sub sp,8 ; alloc variables
mov ax,offset parambuf
mov [dirp],ax ; dirp will be initialized first
; each time we start from root directory
w1loop:
mov ax,offset fulpath
mov [startp],ax ; startp initialize
mov ax,1 ; get root directory inode
push ax
call getinode
pop ax
call nextchar
mov [bp-4],al ; save char
cmp al,47 ; '/'
je w2loop
; debug
cmp al,35 ; '#'
jne w1loop
mov ax,[fn] ; how many files have been processed
push ax
mov ax,offset prom ; printf(%d files have been converted!','$',fn)
push ax
; call printf
pop cx
pop cx
mov sp,bp
pop bp
pop es
pop ds
ret ; eatpath end here
w2loop: ; while((c = nextchar()) != '$')
call nextchar
mov [bp-4],al
cmp al,36 ; '$'
; debug
je w1loop ; process next path
cloop:
; al can't be used again
; so fetch the char from stack
; guarantee the consistence
mov ax,[bp-4]
cmp al,'$'
jne enext1
mov ax,offset fulstr
push ax
mov ax,offset sucessmes
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
call wrtfile
; no parameter, use the side effect of eatpath
; it increases fn depending on the success of
; DOS file I/O
; mov ax,offset fulstr
; push ax
; mov ax,offset sucessmes
; push ax
; call printf
; pop cx
; pop cx
; mov ax,offset newline
; push ax
; call printf
; pop cx
dec word ptr [dirp]
jmp w1loop ; try to find next path
; no need to ajust display string
; we guarantee it is all right
enext1:
; if there's another component, the inodeinfo
; structure should contain the information of
; a directory inode, we need to change the data
; segment to access this information
push ds ; save original value
mov ax,overlap
mov ds,ax
assume ds:overlap
mov ax,[inodeinfo.i_mode]
pop ds
assume ds:dseg ; restore data segment
and ax,I_TYPE ; determine inode type
cmp ax,I_DIRECTORY
je enext2
dec word ptr [dirp]
dec word ptr [dirp]
dec word ptr [startp]
dec word ptr [startp]
mov si,[startp]
mov byte ptr [si],36 ; '$' indicates the end of fulstr
mov ax,offset fulstr
push ax
mov ax,offset illegmes
push ax
call printf ; illegal path component encounted
pop cx
pop cx
mov ax,offset newline
push ax
call printf ; line return
pop cx
jmp w2loop ; without increase fn
enext2:
; gather up name into
; dir buffer allocate in global data segment
mov ax,offset dbuf
mov [bp-6],ax ; cp = &dbuf
; path component > 14 byte will be truncated
w3loop:
; nextchar subroutine will generate second
; side effect if the swtch is on
mov byte ptr [swtch],1 ; let startp pointer stepping
mov ax,[bp-4]
cmp al,47 ; '/'
je w4loop
cmp al,36 ; '$'
je w4loop
mov ax,offset dbuf
add ax,14
cmp ax,[bp-6]
jbe enext3
mov ax,[bp-4]
mov si,[bp-6]
mov [si],ax
inc word ptr [bp-6] ; *cp++ = c
enext3:
call nextchar
mov [bp-4],ax
jmp w3loop
w4loop:
mov ax,[bp-6]
mov bx,offset dbuf
add bx,14
cmp ax,bx
jnb enext4
mov si,[bp-6]
mov byte ptr [si],0 ; feed gap
inc word ptr [bp-6]; ; *cp++ = 0
jmp w4loop
enext4:
; can't call nextchar bindly
; only [bp-4] == '/'
; this can be called
mov ax,[bp-4]
cmp al,47 ; '/'
jne enext42
call nextchar
mov [bp-4],ax ; skip '/'
enext42:
mov byte ptr [swtch],0 ; stop startp pointer stepping
; we use [bp-2] (16bit) as directory offset
; we haven't seen any directory has 4096 entries
mov word ptr [bp-2],0 ; search from here
; we will determine how many entries
; a directory holds, then we can know
; how to search that, we use a spurious
; address symbol i_size to indicate
; that we only use lower 16bit, to fetch
; this information, we also need to change
; data segment
push ds ; save original value
mov ax,overlap
mov ds,ax
assume ds:overlap
mov ax,[inodeinfo.i_size]
pop ds
assume ds:dseg ; restore data segment
xor dx,dx
mov bx,16
div bx
mov [bp-8],ax ; assign entry count
eloop:
mov ax,[bp-8]
;debug
push ax
mov ax,offset entrynr
push ax
; call printf
pop cx
pop cx
mov ax,offset newline
push ax
; call printf
pop cx
mov ax,[bp-8]
cmp ax,0 ; if the dir has been searched out
jne enext5
dec word ptr [dirp]
dec word ptr [startp]
mov si,[startp]
mov byte ptr [si],36 ; '$'
; end of fulstr
mov ax,offset fulstr
push ax
mov ax,offset errpath
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
jmp w1loop ; no entry matchs just to find next path
enext5:
; if offset is on a block boundary
; read the next directory block
mov ax,[bp-2]
and ax,3ffh ; 1 zone = 1 blk = 1024 byte
cmp ax,0
jne enext6 ; within current dir zone
mov ax,[bp-2]
xor dx,dx
mov bx,1024
div bx ; calculate logic zone #
push ax
call bmap ; convert logic to physical
pop cx
push ax ; zone # to be read
call getzone
pop cx
enext6:
; string compare the directory entry
; and the current component
; if they do not match
; go back to eloop
mov ax,[bp-2]
and ax,3ffh ; we want zone offset
add ax,offset zonespace
mov si,ax
; change es segment to address dent
push es
mov ax,overlap
mov es,ax
assume es:overlap
mov di,offset dent
mov cx,16
cld
repnz movsb
pop es
assume es:dseg
mov ax,[bp-2]
add ax,16 ; stepping
mov [bp-2],ax ; write back
mov ax,[bp-8]
dec ax
mov [bp-8],ax
push ds
mov ax,overlap
mov ds,ax
assume ds:overlap
mov ax,[dent.nr_inode]
pop ds
assume ds:dseg
cmp ax,0
jne enext7
jmp eloop
enext7:
mov ax,offset dbuf
mov [bp-6],ax
w5loop:
push es
mov ax,overlap
mov es,ax
assume es:overlap
mov si,offset dbuf
mov di,offset dent.filename
cld
mov cx,14
repz cmpsb
jz enext8
pop es
assume es:dseg
jmp eloop ; get next entry to see
enext8:
; here's a component matched in a directory
; if ther's more pathname, go back to cloop
; other wise return
pop es
assume es:dseg
push ds
mov ax,overlap
mov ds,ax
assume ds:overlap
mov ax,[dent.nr_inode]
pop ds
assume ds:dseg
push ax ; inode # to fetch
call getinode
pop cx
jmp cloop
eatpath endp
cseg ends
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -