📄 what.asm
字号:
xchg ah,al ; Reverse for two digits
sub ax,'00' ; Adjust from ASCII to numeric
aad ; Convert to binary
jmp SHORT setmode
one: sub al,'0' ; Convert to numeric
setmode: sub ah,ah ; Set mode
int 10h
pop ax ; Restore
gotmode: cbw ; Extend to AX
call BinToDec ; Convert to string
ret
DoVid ENDP
; Procedure VeriCop
; Purpose Check for coprocessor
; Input None
; Output 1 for yes or 0 for no
VeriCop PROC
int 11h ; Check peripherals
test al,10b ; Coprocessor
mov ax,0 ; Assume no (don't change flags)
jz no87 ; No? Done
inc ax ; Yes? Set to 1
no87: call BinToDec ; Convert to string
ret
VeriCop ENDP
; Procedure VerAnsi
; Purpose Check for ANSI driver
; Input None
; Output 1 for yes or 0 for no
VerAnsi PROC
@DispStr ans ; Print ANSI string to get
; cursor position
mov ah,6 ; Check for key
mov dl,0FFh ; in buffer
int 21h
jnz ansi ; Done if ANSI
@DispStr overwrt ; Overwrite ANSI string
sub ax,ax ; 0 if not ANSI
jmp SHORT gotansi
ansi: mov ax,0C06h ; Clear returned ANSI keys
mov dl,0FFh ; out of buffer
int 21h
@DispStr delete ; Delete ANSI string
mov ax,1 ; Set 1 for true
gotansi: call BinToDec ; Convert to string
ret
VerAnsi ENDP
; Procedure GetDir
; Purpose Get the current directory or drive
; Input None
; Output Current directory or drive in "string"; level or drive number in AX
GetDir PROC NEAR
cmp extend,1 ; Extend flag true?
jne directry ; No? Get directory
@GetDrv ; Yes? Get drive
mov ah,al ; Copy
add ah,'A' ; Convert to drive letter
mov string,ah ; Put character in string
inc actual ; Length 1
cbw
ret
directry: mov si,OFFSET string ; Load address for string
mov BYTE PTR [si],"\" ; Insert backslash (DOS doesn't)
inc si ; Point to next
@GetDir si
sub cx,cx ; Count is zero
dec si ; Move pointer back to start
findback: lodsb ; Load
cmp al,"\" ; Is it backslash?
jne notslash ; No? Continue
inc dx ; Yes? Increment level counter
notslash: or al,al ; Is it 0?
loopne findback ; No? Repeat
neg cx ; Negate to get positive count
mov actual,cl ; Put level in variable
xchg ax,dx
ret
GetDir ENDP
; Procedure NoCmd
; Purpose Return error for invalid command
; Input None
; Output None
NoCmd PROC
@DispStr err1 ; Display error and quit
@Exit 0
NoCmd ENDP
; Procedure Byticize
; Purpose Adjust word values to fit in a byte
; Input Value in AX
; Output 255 for word values, else value (no extend) or value*10 (extend)
Byticize PROC
cmp extend,0 ; Is extend flag set?
je sizechk ; No? Check size
sub dx,dx ; Yes? Clear DX
mov bx,10 ; Divide by 10 to get 10-unit chunks
div bx
sizechk: or ah,ah ; Is it 255 or less?
je byteOK
mov al,0FFh ; No? Call it 255
byteok: ret
Byticize ENDP
; Procedure GetArg
; Purpose Parse command line for argument and prompt strings
; Input Command line
; Output Pointer to argument in "arg"; length (or 0 if none) in "larg"
; Pointer to prompt in "prompt"; length (or 0 if none) in "lprompt"
GetArg PROC
push ax
push es ; Swap ES and DS
push ds
pop es
pop ds
white: lodsb ; Load while white space
cmp al,' ' ; Is it space?
je white ; Throw away
cmp al,9 ; Is it tab?
je white ; Throw away
cmp al,'"' ; Is it quote?
je promptit ; Process
cmp al,13 ; Is it carriage return?
je gotarg ; Done
sub cx,cx
qdone: dec si ; Adjust
mov es:arg,si ; Save pointer to argument start
chars: lodsb ; Load while not white
cmp al,' ' ; Is it space?
je nomore ; Done
cmp al,9 ; Is it tab?
je nomore ; Done
cmp al,13 ; Is it carriage return?
loopne chars ; Throw away
nomore: not cx ; Adjust count
mov es:larg,cx ; Save length
jmp SHORT gotarg
promptit: mov di,si ; Save pointer to start
sub cx,cx ; Clear count
inprompt: lodsb ; Another
cmp al,13 ; Is it carriage return?
je oneq ; Yes? Treat one quote like character
cmp al,'"' ; Is it quote?
loopne inprompt ; No? Throw away
mov es:prompt,di ; Save prompt pointer
not cx
mov es:lprompt,cx ; and length
jmp SHORT white ; Get the argument
oneq: mov si,di ; Restore
mov cx,-1 ; Set count to -1
jmp SHORT qdone
gotarg: push es ; Swap ES and DS back
push ds
pop es
pop ds
pop ax
ret
GetArg ENDP
; Procedure ShowPrmpt
; Purpose If prompt, display it
; Input Pointer to prompt
; Output Prompt to screen
ShowPrmpt PROC
cmp prompt,0 ; Is there a prompt?
je noshow ; If not, continue
push ds ; Save and restore DS
@Write prompt,lprompt,,es ; DOS Write function
pop ds
noshow: ret
ShowPrmpt ENDP
; Procedure DoEnviron
; Purpose Convert a string to an environment variable
; Input String in "string"
; Output String in "WHAT" environment variable;
; AX has 0 for success, nonzero for failure
DoEnviron PROC
call GetEnv ; Get environment size, length, address
mov dx,ax ; Save size and length
mov bx,cx
; Find "WHAT="
sub di,di ; Point to start
sub al,al ; Search for zero
mov si, OFFSET what ; Point source at "WHAT="
findwh: repne scasb ; Search
cmp BYTE PTR es:[di],0 ; If double null, end of environment
je gotend
jcxz noroom ; Error if not found
push di ; Save
push cx
mov si,OFFSET what ; Load address and length of "what"
mov cx,lwhat ; for comparison
repe cmpsb ; Compare
mov si,di ; Make copy
pop cx ; Restore
pop di
jnz findwh
; Find end of "WHAT" variable
xchg di,si
repne scasb ; Find end of environment variable
xchg si,di ; Point source to next variable
; Calculate characters left to write
mov cx,bx ; Load total characters
sub cx,si ; Subtract finished to get left
; Move everything back to overwrite "WHAT="
movenv: push ds ; Save DS
mov ax,es ; Copy to ES
mov ds,ax
rep movsb ; Copy
mov BYTE PTR es:[di],0 ; Put null at end in case of error
pop ds ; Restore
; Check environment space
gotend: mov al,actual ; Load length of string
sub ah,ah ; Clear top
add ax,lwhat ; Add length of name
add ax,di ; Add position to get final length
cmp ax,dx ; Is it longer than environment?
jge noroom ; Yes? Quit
; Put WHAT= at end
mov si,OFFSET what ; Load address and length of what
mov cx,lwhat
rep movsb
; Put new string at end
mov si,OFFSET string ; Load address and length of string
mov cl,actual
rep movsb
mov WORD PTR es:[di],0 ; Put double null at end
sub ax,ax ; Return 0 for success
ret
noroom: inc ax ; Return nonzero for fail
ret
DoEnviron ENDP
; Procedure GetEnv
; Purpose Find and measure the environment
; Input None
; Output Segment of environment in ES, size in AX, length in CX
GetEnv PROC
mov dx,es:10h ; Load segment of COMMAND.COM
mov es,dx ; into ES
mov ax,es:2Ch ; Load COMMAND.COM's environment
or ax,ax ; Is it 0?
jnz secondry ; No? This is a secondary command
; and we have its environment in AX
dec dx ; Yes? This is original COMMAND.COM
mov es,dx ; so point ES to paragraph before PSP
add dx,es:03 ; Offset of environment is 3 bytes in
add dx,2 ; Adjust it back to PSP
mov ax,dx ; Put it in AX
secondry:
; Note:
; CodeView cannot debug the previous section of code, because the PSP
; addresses checked by the code are those passed from DOS to CodeView,
; not addresses passed from DOS to the program. To debug with CodeView,
; find the actual address of the environment:
; S 500:0 L FFFF "COMSPEC="
; When you find the actual address, hard code it into your program:
; mov ax,110Ch ; Debug line
; Comment the line out for final assembly after debugging.
mov si,ax ; Save a copy
sub dx,dx ; Clear DX for multiply
dec ax ; Get paragaraph before environment
mov es,ax ; Load into DS
mov ax,es:03 ; Size in paragraphs is at byte 4
mov cx,16 ; Multiply by 16
mul cx
mov es,si ; Restore environment address
sub di,di ; Point to start
mov cx,ax ; Load maximum count (size of
mov bx,ax ; environment) and save a copy
sub ax,ax ; Search for double null
null2: repne scasb ; Look for null
jz noerr ; If not out of space, continue
sub ax,ax ; else error (return 0)
jmp error2
noerr: cmp BYTE PTR es:[di],0 ; Is it double null?
jne null2 ; No? Look again
mov cx,di ; Yes? Save length in CX
mov ax,bx ; Reload size to AX
ret
GetEnv ENDP
; Procedure BinToDec
; Purpose Convert binary number in AX to string
; Input Value in AX
; Output Value string in "string"; length of string in "actual"
; AL contains number to be converted
BinToDec PROC
push ax
push es
sub cx,cx ; Clear counter
mov bx,10 ; Get ready to divide by 10
getdigit: sub dx,dx ; Clear top
div bx ; Remainder is last digit
add dl,'0' ; Convert to ASCII
push dx ; Put on stack
inc cx ; Count character
or ax,ax ; Is quotient 0?
jnz getdigit ; No? Get another
mov actual,cl ; Save number of digits
mov ax,ds ; Load DS to ES
mov es,ax
mov di,OFFSET string ; Load source
putdigit: pop ax ; Get a digit off stack
stosb ; Store it to string
loop putdigit
pop es
pop ax
ret
BinToDec ENDP
; Procedure UpCase
; Purpose Convert a character to uppercase
; Input Character in AH
; Output Converted character in AH
UpCase PROC
cmp ah,"a" ; Is character below lowercase?
jl ok ; If so, continue
; else
cmp ah,"z" ; Is character above lowercase?
jg ok ; If so, continue
; else
sub ah,20h ; Make it lowercase
ok: ret
UpCase ENDP
; Procedure Help
; Purpose Display syntax screens
; Input None
; Output Help to screen
Help PROC
@DispStr help1 ; First screen
@GetKey ; Pause
@DispStr help2 ; Second screen
@Exit 0
Help ENDP
END start ; End assembly
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -