首页 > 解决方案 > 如何从 FASM 执行 DOS 的 COMMAND.COM 命令?

问题描述

是否有任何 DOS 函数来执行包含 command.com 行的字符串?我需要像 C's 这样的东西system(),但对于 DOS 和 FASM。

标签: assemblydosx86-16fasm

解决方案


我以前使用过这样的代码来执行 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环境块中命名的变量来找到命令解释器的名称。如果没有找到,我们默认为COMMAND.COM. 然后,我们构建一个exec 参数块,其中包含我们想要执行的程序的有用详细信息,包括命令行。这是您需要放置要执行的 shell 命令的地方(以命令行结尾的格式)。最后,我们调用DOS 函数 4b00:execute program来执行命令解释器,运行我们的命令。


推荐阅读