📄 iexecdos.asm
字号:
; Set flag so we know that a command was given.
mov [DosCommandGiven],COMMAND_GIVEN
clc ; No error
@@Exit:
ret
endp ParseDosCommand
dataseg
; Local data area for ExecuteDosCommand
; The following act as pointers to the data for this invocation of
; ExecuteDosCommand.
DirectoryPath dw ?
FileNameSeg dw ?
FileName dw ?
codeseg
proc ExecuteDosCommand
; This procedure actual executes the DOS command, if given, for
; each file that is found.
;
; Input
; ax:si - Offset of filename
; di - offset of currentdir
; Output
; none
; Calling conventions
; NA
; Registers modified
; all except es
mov [DirectoryPath],di
mov [FileNameSeg],ax
mov [FileName],si
push es
cmp [DosCommandGiven],COMMAND_GIVEN
jne @@Exit
; Blank out the buffer for the command to do.
cld ; Autoincrement
mov ax,seg CommandToDo
mov es,ax
mov di,offset CommandToDo
mov cx,COMMAND_BUFFER_LENGTH
mov al,0
rep stosb
; We need to go into a loop of copying from the input command
; string until we find a %
mov di,offset CommandToDo ; For results es:di
xor cl,cl ; Length of output string
inc di ; Move over the leading length byte
mov si,offset StartOfBuff
call CopyAsciizString ; Copy the starting /C
mov si,offset DosCommandBuffer ; For original command ds:si
mov ch,[si] ; Length of original string
inc si ; Move over the leading length byte
@@ProcessChar:
or ch,ch
jz SourceExhausted
lodsb ; Load current byte
dec ch ; One less character to get
cmp al,'%'
je @@ProcessSpecial
@@EmitChar:
stosb ; This route handles regular characters
inc cl ; Increment length of output string
cmp cl,COMMAND_BUFFER_LENGTH-1
jae SourceExhausted ; Force early termination if we run out of room!
jmp @@ProcessChar
@@ProcessSpecial: ; We saw a % sign.
or ch,ch
jz @@EmitChar ;Output because there is nothing more after it
lodsb
dec ch
; Try to recognize one of the %x directives:
cmp al,'1'
je Process1
cmp al,'2'
je Process2
cmp al,'3'
je Process3
cmp al,'4'
je Process4
cmp al,'5'
je Process5
; We don't recognize it, so output the %x unchanged.
mov [byte es:di],'%' ; Put out the % that got us here
inc cl ; Increment length of output string
inc di
jmp @@EmitChar ; Output the character in AL
Process1:
call EmitPath
cmp cl,COMMAND_BUFFER_LENGTH-1
jae SourceExhausted ; Force early termination if we run out of room!
Process2:
call EmitFileRoot
cmp cl,COMMAND_BUFFER_LENGTH-1
jae SourceExhausted ; Force early termination if we run out of room!
jmp Process5
Process3:
call EmitPath
jmp @@ProcessChar
Process4:
call EmitFileRoot
call EmitDot
jmp @@ProcessChar
Process5:
Call EmitDot
call EmitExtension
jmp @@ProcessChar
SourceExhausted:
;We need to fill in the length byte, along with a 13 at the end.
mov al,13
stosb
mov [CommandToDo],cl ; Fill in the length byte
mov cx,seg CommandToDo
mov dx,offset CommandToDo
call DoDosCommand
@@Exit:
pop es
ret
endp ExecuteDosCommand
proc EmitPath
; This routine writes the drive and path to the output command.com string
push si ds
mov si,offset Drive
call CopyPascalString
mov si,[DirectoryPath]
cmp [byte ds:si],'A'
jl @@NoBackSlash
dec si
@@NoBackSlash:
call CopyAsciizString
mov ax,seg SwitchChar
mov ds,ax
mov si,offset SwitchChar
call CopyPascalString
pop ds si
ret
endp EmitPath
proc EmitFileRoot
; This routine writes the part of the filename that is before the
; extension to the output string that will be sent to COMMAND.COM
push si ds
mov si,[FileName]
mov ax,[FileNameSeg]
mov ds,ax
mov al,'.'
call CopyTerminatedString
pop ds si
ret
endp EmitFileRoot
proc EmitExtension
; This routine writes the extension of the current file to the
; output string that will be sent to COMMAND.COM
push si ds
mov si,[FileName]
mov ax,[FileNameSeg]
mov ds,ax
mov al,'.'
@@CheckAgain:
mov ah,[ds:si]
cmp ah,al
je @@DotFound
or ah,ah
jz @@Exit ; Quit searching if a zero is found
inc si
jmp @@CheckAgain
@@DotFound:
inc si
call CopyAsciizString
@@Exit:
pop ds si
ret
endp EmitExtension
proc EmitDot
; This routine outputs a . to the string to be sent to command.com.
mov [byte es:di],'.' ; Put out the .
inc cl
inc di
ret
endp EmitDot
; The following string copy routines are special for this module.
; DS:SI point to the source string. (DS:SI are preserved.)
; ES:DI Point to the destination string area. (ES:DI is not preserved.)
; CL is updated for every byte output to ES:DI.
proc CopyPascalString
; Copy pascal type string to ES:DI, but omit the length byte.
xor bx,bx
mov al,[ds:si]
add cl,al
@@CopyChar:
mov ah,[ds:si+1+bx]
mov [es:di],ah
inc di
inc bx
dec al
jnz @@CopyChar
ret
endp CopyPascalString
proc CopyAsciizString
; Copy a string that is terminated by a zero.
xor al,al
call CopyTerminatedString
ret
endp CopyAsciizString
proc CopyTerminatedString
; Copy a string terminated by any character.
; al contains character to stop copy. Normally 0 for ASCIIZ strings
; Note that the terminator is not copied.
xor bx,bx
@@CopyMoreChar:
mov ah,[ds:si+bx]
cmp ah,al
jz @@AtEnd
mov [es:di],ah
inc di
inc bx
inc cl
jnz @@CopyMoreChar
@@AtEnd:
ret
endp CopyTerminatedString
segment zzzzzseg ; Dummy final segment for calculating program size
; to release memory back to DOS.
ends zzzzzseg
endif ; ifndef MDL
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -