如何从 FASM 执行 DOS 的 COMMAND.COM 命令?
How to execute DOS' COMMAND.COM command from FASM?
是否有任何 DOS 函数可以执行包含 command.com 行的字符串?我需要类似 C 的 system()
,但用于 DOS 和 FASM。
我以前使用过这样的代码来执行 DOS shell 命令。它适用于 nasm,但您可以根据自己的目的对其进行调整。此代码专门将我们自己的命令行尾部作为 DOS 命令执行,但如果您想执行不同的命令,您可以修补一些其他命令行尾部。
section .data
comspec db "COMSPEC=" ; for finding COMSPEC in the env block
comlen equ $-comspec
command db "COMMAND.COM",0
; EXEC parameter block
execpar dw 0 ; environment for child (use ours)
dw 80h, 0h ; command tail (use ours)
dw 5Ch, 0h ; first FCB (use ours)
dw 6Ch, 0h ; second FCB (use ours)
section .text
; execute DOS command
doexec:
mov bx, execpar ; EXEC parameter block
mov [bx+4], cs ; fix up segment for command tail
mov [bx+8], cs ; fix up segment for first FCB
mov [bx+12], cs ; fix up segment for second FCB
call fndcom ; write pointer to COMSPEC value to DS:SI
mov dx, si
mov ax, 4B00h ; LOAD AND EXECUTE PROGRAM
int 21h
jnc .ok ; error occured?
push ax ; remember error code
call fndcom ; find COMSPEC value anew
pop ax ; restore error code
call perror ; print error message
.ok: push cs ; restore ds
pop ds
ret
; find COMSPEC in the environment block
; and load pointer to it to DS:SI
; preserves bx
fndcom: mov ds, [2Ch] ; environment block
xor si, si ; beginning of env block
; loop invariant: si points to the beginning of
; a string in the environment
.loop1: cmp byte [si], 0 ; end of environment reached?
je .nope
mov di, comspec ; find "COMSPEC="
mov cx, comlen ;
repe cmpsb ; compare strings
je .found ; if found, we are done
dec si ; go back to mismatched character
.loop2: lodsb ; search si for end of string
test al, al ; end of string reached?
jne .loop2 ; nope
jmp .loop1 ; check next string in environment
; COMSPEC unset
.nope: push cs
pop ds ; restore ds
mov si, command ; "COMMAND.COM"
ret
; COMSPEC found
.found: ret
基本思路是通过在环境块中搜索名为COMSPEC
的变量来查找命令解释器的名称。如果找到 none,我们默认为 COMMAND.COM
。然后,我们构建一个exec parameter block with useful details for the program we would like to execute, including the command line. This is where you need to put the shell command to be executed (in the format of a command line tail). Finally, we invoke DOS function 4b00: execute program来执行命令解释器,运行我们的命令。
是否有任何 DOS 函数可以执行包含 command.com 行的字符串?我需要类似 C 的 system()
,但用于 DOS 和 FASM。
我以前使用过这样的代码来执行 DOS shell 命令。它适用于 nasm,但您可以根据自己的目的对其进行调整。此代码专门将我们自己的命令行尾部作为 DOS 命令执行,但如果您想执行不同的命令,您可以修补一些其他命令行尾部。
section .data
comspec db "COMSPEC=" ; for finding COMSPEC in the env block
comlen equ $-comspec
command db "COMMAND.COM",0
; EXEC parameter block
execpar dw 0 ; environment for child (use ours)
dw 80h, 0h ; command tail (use ours)
dw 5Ch, 0h ; first FCB (use ours)
dw 6Ch, 0h ; second FCB (use ours)
section .text
; execute DOS command
doexec:
mov bx, execpar ; EXEC parameter block
mov [bx+4], cs ; fix up segment for command tail
mov [bx+8], cs ; fix up segment for first FCB
mov [bx+12], cs ; fix up segment for second FCB
call fndcom ; write pointer to COMSPEC value to DS:SI
mov dx, si
mov ax, 4B00h ; LOAD AND EXECUTE PROGRAM
int 21h
jnc .ok ; error occured?
push ax ; remember error code
call fndcom ; find COMSPEC value anew
pop ax ; restore error code
call perror ; print error message
.ok: push cs ; restore ds
pop ds
ret
; find COMSPEC in the environment block
; and load pointer to it to DS:SI
; preserves bx
fndcom: mov ds, [2Ch] ; environment block
xor si, si ; beginning of env block
; loop invariant: si points to the beginning of
; a string in the environment
.loop1: cmp byte [si], 0 ; end of environment reached?
je .nope
mov di, comspec ; find "COMSPEC="
mov cx, comlen ;
repe cmpsb ; compare strings
je .found ; if found, we are done
dec si ; go back to mismatched character
.loop2: lodsb ; search si for end of string
test al, al ; end of string reached?
jne .loop2 ; nope
jmp .loop1 ; check next string in environment
; COMSPEC unset
.nope: push cs
pop ds ; restore ds
mov si, command ; "COMMAND.COM"
ret
; COMSPEC found
.found: ret
基本思路是通过在环境块中搜索名为COMSPEC
的变量来查找命令解释器的名称。如果找到 none,我们默认为 COMMAND.COM
。然后,我们构建一个exec parameter block with useful details for the program we would like to execute, including the command line. This is where you need to put the shell command to be executed (in the format of a command line tail). Finally, we invoke DOS function 4b00: execute program来执行命令解释器,运行我们的命令。