如何从 FASM 执行 DOS 的 COMMAND.COM 命令?

问题描述

是否有任何 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 的变量来找到命令解释器的名称。如果没有找到,我们默认为 COMMAND.COM。然后,我们构建一个 exec parameter block,其中包含我们想要执行的程序的有用细节,包括命令行。这是您需要放置要执行的 shell 命令的地方(以命令行尾部的格式)。最后,我们调用 DOS function 4b00: execute program 来执行命令解释器,运行我们的命令。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...