home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast.iso
/
sysutil
/
exec3.asm
< prev
next >
Wrap
Assembly Source File
|
1994-03-05
|
6KB
|
272 lines
PAGE 55,132
;
; name exec -- system call for .EXE files
;
; synopsis status = exec(cmd);
; int status; error returns
; char *cmd; command to execute
;
;
; description This function accepts a string with the pathname and
; parameters of a command to be executed and executes it.
; See Appendix F. of the DOS 2.0 Reference Manual for more
; information.
;
; returns 0: Successful
; -1: Insufficient Memory
; -2: Access Denied
; -3: No such command
; -4: Invalid command format
; -5: Memory control blocks destroyed
; -6: Invalid memory block address
;
; cautions Use only with .EXE files built with the Lattice C
; compiler, and linked with C.OBJ.
;
; authors Written by Darrel Plank. Modified from the macro by Brad
; Davis (b-davis@utah-cs). The prolog and epilog are modified
; from Jim Holtman's macros for Pascal. Modified by Marco Papa
; (papa.use-cse@csnet-relay) to work with .EXE files.
;
PROLOG MACRO
PUSH BP
MOV BP,SP
ENDM
EPILOG MACRO NUM
POP BP
RET
ENDM
EXECVAL EQU 0
OVLVAL EQU 3
FNCINT EQU 21H
SETBLK EQU 4AH
EXECF EQU 4BH
CR EQU 0DH
PSP STRUC
INTVECT DW ?
TOM DW ?
RES1 DB ?
DOSLONG DB 5 DUP (?)
TERMINA DD ?
CTRLBRK DD ?
CRITERR DD ?
DOS1 DB 22 DUP (?)
ENVIRO DW ?
DOS2 DB 46 DUP (?)
FPA1 DB 16 DUP (?)
FPA2 DB 20 DUP (?)
UPA DB 128 DUP (?)
PSP ENDS
EXECDEF STRUC
NENVIRO DW
COMMND DW 2 DUP (0)
FCB5CH DW 2 DUP (0)
FCB6CH DW 2 DUP (0)
EXECDEF ENDS
PGROUP GROUP PROG
PROG SEGMENT BYTE PUBLIC 'prog'
ASSUME CS:PGROUP
PUBLIC EXEC
EXEC PROC NEAR
PROLOG
PUSH DS
PUSH ES
;
; free up as much memory as we can
;
MOV AX,CS ; Code Segment to AX
PUSH ES ; Save ES for later
SUB AX,10H ; point to PSP ****
MOV ES,AX
MOV BX,SS
SUB BX,AX
ADD BX,1000H ; 64K for stack segment
MOV AH,SETBLK
INT FNCINT
JNC NEAR PTR LBL1
POP ES
JMP NEAR PTR LBL2
LBL1: POP ES ; Get ES's original value
;
; Save SS and SP registers
;
MOV CS:SPSAVE,SP
MOV CS:SSSAVE,SS
;
; set up the parameter block
;
MOV CS:EXECBLK.NENVIRO,0 ; Inherit envir. from parent
MOV AX,3700H ; Undocumented call for SWITCHAR
;
; W A R N I N G: The following function call is undocumented and is
; liable to disappear or change in future versions of DOS.
;
INT FNCINT
MOV CS:COMMAND[1],DL ; Switchar
MOV DX,4[BP] ; Address of the command
MOV SI,DX
MOV DI,DX
CLD
XOR AL,AL
MOV CX,100H ; Longest string can be 100h
REPNE SCASB ; Find Null termination
SUB DX,DI
NEG DX
MOV CX,DX
DEC CX
ADD DX,2
MOV CS:COMMAND[0],DL ; Save command length
LEA DI,CS:COMMAND[4]
MOV AX,CS
MOV ES,AX
REP MOVSB ; Copy command into our buffer
ASSUME DS:PGROUP
MOV AX,CS
MOV DS,AX ; DS points at code segment
MOV BYTE PTR [DI],CR ; Put in Carriage Return
LEA DX,COMMAND
MOV EXECBLK.COMMND[0],DX
MOV EXECBLK.COMMND[2],DS
MOV BX,OFFSET EXECBLK
SUB AX,10H ; AH points to PSP ****
MOV DS,AX ; DS points to PSP also ****
XOR SI,SI
MOV DS,[SI].ENVIRO ; Get environment address
ASSUME DS:NOTHING
LEA SI,CS:COMSPEC ; Point SI at env. variable name
PUSH DS ; Swap
PUSH ES ; ES
POP DS ; and
POP ES ; DS
CALL GETENV
PUSH DS ; Swap
PUSH ES ; them
POP DS ; back
POP ES ; again
MOV AH,EXECF
MOV AL,EXECVAL ; OVLVAL here for overlay
INT FNCINT
MOV SS,CS:SSSAVE
MOV SP,CS:SPSAVE
JC NEAR PTR LBL2
MOV AX,0 ; Successful exec
JMP NEAR PTR FINE
LBL2: MOV SI,AX
MOV AL,CS:ERRORS[SI] ; Get error code
MOV AH,0FFH ; Sign extension - Assume Negative
FINE: POP ES
POP DS
EPILOG 1
EXECBLK EXECDEF <>
;
; first byte of command is length excluding the length byte and the
; trailing \r. Second byte is switchar.
;
COMMAND DB 2 DUP(?),"C ",254 DUP(?)
COMSPEC DB "COMSPEC",0
SPSAVE DW
SSSAVE DW
ERRORS DB ?
DB ?
DB -3 ; No such command
DB ?
DB ?
DB -2 ; Access denied
DB ?
DB -5 ; Memory control blocks destroyed
DB -1 ; Insufficient memory
DB -6 ; Invalid memory block address
DB ?
DB -4 ; Invalid command format
EXEC ENDP
;
; Getenv expects ES to have the environment paragraph and DS:SI to point
; to an ASCIIZ string with the desired environment variable in it.
; It returns the address of the proper string in ES:DX.
;
PUBLIC GETENV
GETENV PROC NEAR
PROLOG
PUSH AX
PUSH CX
PUSH SI
PUSH DI
MOV CS:VARNAME,SI ; Save offset of env. name
XOR DI,DI
;
; At this point ds:si points to dummy variable environment name and
; es:di points to environment.
;
CLD ;Forward string operations
TOP:
LODSB ;Get a char. of env. name
CMP AL,0 ;If we're at the end
JNE NEAR PTR LBL3
CMP BYTE PTR ES:[DI],'=' ;Check for match
JNE NEAR PTR LBL4
;
; We matched
;
INC DI ;Move beyond '='
MOV DX,DI
POP DI
POP SI
POP CX
POP AX
EPILOG 2
LBL4:
;
; At this point we found the end of the Env. variable name but it didn't
; match because the env. string was too long
;
MOV CX,-1
REPNE SCASB ;Find the end of the env. string
CMP BYTE PTR ES:[DI],0
JNE LBL3
MOV AX,-1 ;End of environment area
POP DI
POP SI
POP CX
POP AX
EPILOG 2
LBL3:
;
; Check if the next character matches
;
AND AX,11011111b ;Capitalize the character in ax
SCASB
JE TOP
;
; If we get here we don't have a match so move on
;
MOV SI,CS:VARNAME ;Go back to start of env. string
XOR AX,AX
MOV CX,-1
REPNE SCASB ;Go to next env. variable
CMP BYTE PTR ES:[DI],0
JNE TOP
MOV AX,-1 ;End of environment area
POP DI
POP SI
POP CX
POP AX
EPILOG 2
VARNAME DW ?
GETENV ENDP
PROG ENDS
END