Microsoft KB Archive/46879

COBOL 2.x Can’t Execute DOS Batch Files; Can CHAIN Assembly

PSS ID Number: Q46879 Article last modified on 04-20-1993

2.00 2.10 2.20 MS-DOS

Summary: Microsoft COBOL Versions 2.0, 2.1, and 2.2 cannot directly CALL or execute a DOS batch file. The easiest technique to execute a DOS batch file from a COBOL 2.x program is to start a DOS batch file that, in turn, runs a COBOL program. When it stops, the COBOL program drops back to the batch file, and the batch file continues. To execute a DOS batch file from a COBOL 2.x program without first starting a batch file, you must first CHAIN to an assembly language routine that, in turn, execute the DOS EXEC function to run the DOS batch file (see Code Example below).

More Information: COBOL 2.x does not provide the support for executing DOS batch files. COBOL 3.0 and 3.0a provide this capability with built-in functions that implement special features. For example, in COBOL 3.0, CALL X“91” function 35 can be used to execute a DOS program. Upgrading to COBOL 3.0a gives you this ability.

Code Example
COBOL 2.x can CHAIN to an assembly language routine that can execute the DOS interrupt 21 Hex with function 4B Hex (the DOS EXEC function), which can run a DOS batch file, return to assembler, and drop back to DOS. Below are three files, TEST.COB, HELLO.BAT, and EXEC.ASM. Compile in COBOL Versions 2.x as follows: COBOL TEST.COB; Assemble and link (such as with Microsoft Macro Assembler Version 5.1) as follows: MASM EXEC.ASM; LINK EXEC.OBJ; You can now run the COBOL program as follows: RUNCOB TEST The COBOL routine TEST.INT will CHAIN to the assembler routine EXEC.EXE, which runs the batch file HELLO.BAT, returns, and then drops back to DOS. For more information on the DOS EXEC function, INT 21 function 4B Hex, consult one of the following two books: Ray Duncan and Richard Wilton. “Advanced MS-DOS Programming.” Redmond, WA. Microsoft Press, 1985. Ray Duncan. “MS-DOS Encyclopedia.” Redmond, WA. Microsoft Press, 1988.

TEST.COB
IDENTIFICATION DIVISION. PROGRAM-ID. TEST. ENVIRONMENT DIVISION. DATA DIVISION. PROCEDURE DIVISION. MAIN. DISPLAY &quot;CALLING BATCH FILE.....&quot;. CHAIN &quot;EXEC&quot;. STOP RUN.

HELLO.BAT
REM This is the batch file. ECHO Hello World

EXEC.ASM
TITLE  EXEC DOSSEG .MODEL SMALL .STACK 100h
 * ******************************************************************* ; ; Define and set up data area, defining the program to be ; executed with the DOS EXEC function and also the command ; tail to have executed. ; ; ; * * * * IMPORTANT * * *  ; ; You must replace the filename variable with the ; path of your command.com program and the comtail variable ; with the name of the batch file you want to execute. ; ; ****************************************************************** .DATA COMTAIL DB 12,‘/C HELLO.BAT’,13 ; Batch file to be run. FILENAME DB ‘C:.COM’,0; Load and run the COMMAND.COM PARAMETERS DW ? ; and pass the batch file as the COMOFF DW ? ; command tail. COMSEG DW ? ; Make space for SEG and OFFSET. GARBAGE DW 4 DUP(0) ; Rest of parameters all zeros. ; ******************************************************************* ; ; Start of code section for program to call the DOS EXEC function ; INTERRUPT 21H FUNCTION 4BH. ; ; ******************************************************************* .CODE JMP Start Keep_SS DW 0 ; Variable to keep SS Keep_SP DW 0 ; Variable to keep PS Start: MOV AX,@DATA MOV DS,AX ; ******************************************************************* ; ; Move the SEGment and OFFSET of the command tail into the ; variables of the parameter block. This is the command ; tail of the program being executed. ; ; ******************************************************************* MOV AX,SEG COMTAIL ; Set up parameter block with SEG MOV COMSEG,AX ; and OFFSET of command tail to be MOV AX,OFFSET COMTAIL ; executed. MOV COMOFF,AX ; ******************************************************************* ; ; Obtain the size of the current program and call INTERRUPT 21H ; FUNCTION 4AH to modify the memory block to allow another process ; to load and run. ; ; ******************************************************************* MOV AX,ES ; Let AX = segment of PSP base. MOV BX,SS ; Let BX = segment of stack base. SUB BX,AX ; Reserve seg stack - seg psp. ADD BX,100h / 16 ; plus paragraphs of stack. MOV AH,4AH ; Function number. INT 21H ; Modify the memory block. ; ******************************************************************* ; ; Set up the ES and BX registers to contain the SEGment and OFFSET ; of the parameter block, respectively. ; ; ******************************************************************* MOV AX,SEG PARAMETERS ; Let ES = segment of parameter MOV ES,AX ; block. MOV BX, OFFSET PARAMETERS; Let BX = offset of parameter ; block. ; ******************************************************************* ; ; Save the values of SS and PS because these values are altered ; during the DOS EXEC function. ; ; ******************************************************************* MOV AX,SS ; Let Keep_SS = SS. MOV CS:KEEP_SS, AX MOV AX,PS ; Let Keep_SP = SP. MOV CS:KEEP_SP, AX ; ******************************************************************* ; ; Set up the DX and DS registers to contain the SEGment and OFFSET ; of the filename string to be executed, respectively. ; ; ******************************************************************* MOV DX,OFFSET FILENAME ; Let DX = offset of filename. MOV AX,SEG FILENAME ; Let DS = segment of filename. MOV DS,AX ; ******************************************************************* ; ; Perform the DOS EXEC function on the filename and parameter block ; specified in the DATA section of this code. ; ; ******************************************************************* MOV AH,4BH ; DOS EXEC function. MOV AL,0 ; Select “LOAD AND RUN” option. INT 21H ; Run the program. ; ******************************************************************* ; ; After DOS EXEC function returns, restore the registers back to ; their original values. ; ; ******************************************************************* MOV AX,CS ; Restore DS. MOV DS,AX MOV SS,CS:Keep_SS ; Restore SS. MOV PS,CS:Keep_SP ; Restore SP. ; ******************************************************************* ; ; Load DOS exit function to perform return back to DOS normally. ; ; ******************************************************************* MOV AX,04C00h INT 21H ; ******************************************************************* ; ; Create a ‘Dummy Segment’ to mark the end of the code. ; ; ******************************************************************* ZSEG SEGMENT ZSEG ENDS END

Additional reference words: 2.00 2.10 2.20 Copyright Microsoft Corporation 1993.