⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iexecdos.asm

📁 还是一个词法分析程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:

;   FILENAME: IEXECDOS.ASM
;
;   Copyright (c) 1990, 1992 by Borland International, Inc.
;
;   DESCRIPTION: This module implements the routines that handle calling
;   DOS to perform a command on each file that is found by WHEREIS.
;   This module uses ideal mode syntax.
;
;   This module looks for the location of COMMAND.COM to enable the
;   running of the commands. Since many matching files may be found,
;   and COMMAND.COM is called to execute the given DOS command for each
;   file that is found, it is best if COMMAND.COM is located in a ramdisk.
;
;   ASSEMBLY INSTRUCTIONS: To assemble this module use the following
;   TASM command line.
;
;       TASM /m /dMDL=memorymodel iparam
;
;   /m in the above command line allows TASM to resolve jumps and other
;   operations to their shortest form and get rid of extra NOPs.
;   'memorymodel' in the above command line may be replaced by TINY, SMALL,
;   MEDIUM, COMPACT, LARGE or HUGE. If assembling this module to run on
;   a 286/386 machine, turn on the P286 directive in order to take advantage of
;   286/386 specific instructions. I.E.
;
;       TASM /m /dMDL=memorymodel /jP286 iparam
;

;DO_SAMPLE_COMMAND equ 1      ; Enable this to execute a sample DIR command
;                             ;   when the command line is being parsed.

jumps

%tabsize 4

ifndef  MDL
    display "Error: This module requires that you provide a memory model"
    display "       definition on the command line. I.E. /dMDL=SMALL."
    err ; Force a fatal error
else

    ideal                           ; Use TASM's Ideal mode
%   model   MDL,pascal              ; Define the memory model

    include "dos.inc"
    include "idos.inc"
    include "kbd.inc"
    include "iwhglobl.inc"
    include "imacros.mac"

    dataseg
NO_COMMAND_GIVEN equ 0
COMMAND_GIVEN    equ 1
    DosCommandGiven   db NO_COMMAND_GIVEN

COMMAND_BUFFER_LENGTH equ 200
    ; Stores the command given on command line
    DosCommandBuffer  db COMMAND_BUFFER_LENGTH dup (?)

; The DOS command in quotes will include some special escape sequences
; that will cause the name of the file to be inserted in various ways.
;
;  %1  - The full path, filename and  extension
;  %2  - Filename and extension (no path)
;  %3  - Only the path
;  %4  - Only the filename before the extension followed by a .
;  %5  - Only the extension, preceeded by a .

    ; This is placed at the start of COMMAND.COM command strings.
    StartOfBuff       db '/C ',0

    ; Store the actual command that is executed. Any %x directives in
    ; the above command buffer are converted to their actual values
    ; as the above command is transfered into the following buffer.
    ; 32 extra bytes are an overrun buffer.
    CommandToDo       db COMMAND_BUFFER_LENGTH+32 dup (?)

    ; Needed for the call to execute COMMAND.COM
    ParamBlock        dw 7 dup (0)

    ComspecTag        db 'COMSPEC=',0

    ; Pointer into the environment block for start of COMMAND.COM location
    ComspecSeg        dw 0     ;Not changed from zero if no comspec found.
    ComspecOfs        dw ?

    MakePascalString  NoComspecMssg,<"COMSPEC= not found in environment!",13,10>

    codeseg

    ; The environment block is a group of null terminated strings.
    ; A string beginning with zero signals the end of the eviroment block.

    proc SearchEnvironment
    ;   This routine searches for a variable in the environment block.
    ;
    ;   Input
    ;       DS:SI - Points to a string like "NAME=" which is to be
    ;               found in the environment. It should be an ASCIIZ string.
    ;   Output
    ;       If the variable is found,
    ;           AL    -  0
    ;           ES:DI -  Points to string after the = sign in the environment.
    ;       If the variable is not found,
    ;           AL is nonzero.
    ;   Registers modified
    ;       all

        cld       ;Set direction for scanning to increment

        ; Set ES:DI to environment block
        push   ds
        mov    ax,@data   ; Reset to our datasegment since the "NAME="
                          ; might be in another segment.
        mov    ds,ax
        mov    es,[PspAddress]
        mov    es,[es:psp.EnvironmentBlock]
        xor    di,di
        pop    ds
    @@CheckEnvironmentEnd:
        mov    bx,si               ;initialize BX pointer to name to find
        mov    al,[byte es:di]
        or     al,al
        je     @@MatchFailed       ;jump if end is found

    @@CheckNextByte:

        mov    al,[bx]                  ;get character to match.

        or     al,al                    ;if end of name we are done!
        jz     @@MatchCompleted         ;  (AL will be zero)

        cmp    al,[byte es:di]          ;compare to char in environment block
        jne    @@FindNextString         ;jump if match failed
        inc    bx
        inc    di
        jmp    @@CheckNextByte

    @@FindNextString:
        xor    al,al                    ;scan forward in Environment Block
        mov    cx,0FFFFh                ;for zero byte.
        repnz  scasb
        jmp    @@CheckEnvironmentEnd    ;go compare next string

    @@MatchFailed:
        inc    al                       ;return al<>0 as failure flag

    @@MatchCompleted:                   ;all matched, return ES:DI pointing
                                        ; to parameter. al = 0
        ret
    endp SearchEnvironment


ifdef DO_SAMPLE_COMMAND
    ; Show a sample of the proper way to call COMMAND.COM
    dataseg
    SampleCommand db 9,'/C DIR C:',13
    codeseg
    proc SampleDosCommand
    ;   This routine calls COMMAND.COM to do the DIR command.
    ;
        mov     cx,seg SampleCommand
        mov     dx,offset SampleCommand
        call    DoDosCommand
        ret
    endp SampleDosCommand
endif

    proc DoDosCommand
    ;   This procedure executes the command string pointed at by DX:CX
    ;   by giving it to COMMAND.COM.
    ;   This routine is not reentrant because of local code segment
    ;   data storage at end of routine.
    ;
    ;   Input
    ;       None
    ;   Output
    ;       None
    ;   Calling conventions
    ;       NA
    ;   Registers modified
    ;       all

        push    ds
        mov     ax,seg ParamBlock
        mov     es,ax
        mov     bx,offset ParamBlock

        mov     [word es:bx+4],cx   ; Load the location of the command tail
        mov     [word es:bx+2],dx   ;   for the command.

        mov     [Orig_SS],SS
        mov     [Orig_SP],SP

        mov     ax,[ComSpecSeg]
        or      ax,ax
        jz      @@Skip       ; Skip over EXEC if our segment is still zero.
                             ; That means that no Comspec was found.

        mov     dx,[ComspecOfs]
        mov     ds,ax
        
        mov     ax,4b00h
        int     21h
    @@Skip:
        mov     ss,[Orig_SS]
        mov     sp,[Orig_SP]
        pop     ds
        ret

    ; Preserves the location of our stack.
    Orig_SS dw ?
    Orig_SP dw ?
    endp DoDosCommand

    proc ParseDosCommand
    ;   This procedure initializes all variables and data structures
    ;   used for executing the DOS command.
    ;
    ;   Input
    ;       ES:DI - Points to DOS command which is surrounded by quotes.
    ;               It is a pascal style string
    ;   Output
    ;       Carry set if a command has already been specified
    ;   Calling conventions
    ;       NA
    ;   Registers modified
    ;       all

        cmp     [DosCommandGiven],COMMAND_GIVEN
        jne     @@FirstUse
        stc     ; An error because a command was already specified
        jmp     @@Exit

    @@FirstUse:
        push    es di           ; Preserve pointer to DOS command
        ; We need to find COMMAND.COM before we can know that we can
        ; do a DOS command.
         mov    si,offset ComspecTag     ;DS:SI string to match
         call   SearchEnvironment        ;go search environment
         or     al,al
         jne    ComspecNotFound

         mov    [ComspecSeg],es          ; If it was found, ES:DI is stored.
         mov    [ComspecOfs],di
         jz     FreeExtraMemory

    ComspecNotFound:
         call   WritePascalString,ds,offset NoComspecMssg

    FreeExtraMemory:
        ; We need to give up extra memory.
        mov     bx,zzzzzseg     ; Location of first segment of free memory
        mov     ax,[PspAddress] ; PSP segment
        sub     bx,ax           ; BX now contains paragraphs used
                                ;   by this program.
        mov     es,ax
        mov     ah,4ah
        int     21h

ifdef DO_SAMPLE_COMMAND
        call    SampleDosCommand
endif
        pop     di es           ; Restore pointer to DOS command

        ; Check if the final character is a quote and
        ;   remove it if it is.
        xor     bh,bh           ; Get length of string in BX
        mov     bl,[es:di]

        mov     al,[es:di+bx]   ; Load last character of string
        call    IsDelimiter
        jnc     RemoveLeadingQuote

    RemoveTrailingQuote:
        dec     [byte ES:DI]    ; Remove the trailing delimiter

    RemoveLeadingQuote:
        push    es di           ; Preserve the location of the DOS command
        mov     cx, 1           ; Remove the first character
        mov     ax, 1           ; from the string
        call    DeleteChar,es,di
        pop     di es           ; Restore the location

        ; Copy the command to the DOS command buffer
        xor     ah,ah
        mov     al,[byte es:di]
        inc     ax

        call    ByteCopy,es,di,seg DosCommandBuffer,Offset DosCommandBuffer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -