[Chapter Nineteen][Previous] [Next] [Art of Assembly][Randall Hyde]

Art of Assembly: Chapter Nineteen


19.1.4 - Exception Handling in DOS: Traps
19.1.5 - Redirection of I/O for Child Processes

19.1.4 Exception Handling in DOS: Traps


In addition to the break and critical error exceptions, there are the 80x86 exceptions that can happen during the execution of your programs. Examples include the divide error exception, bounds exception, and illegal opcode exception. A well-written application will always handle all possible exceptions.

DOS does not provide direct support for these exceptions, other than a possible default handler. In particular, DOS does not restore such vectors when the program terminates; this is something the application, break handler, and critical error handler must take care of.


19.1.5 Redirection of I/O for Child Processes


When a child process begins execution, it inherits all open files from the parent process (with the exception of certain files opened with networking file functions). In particular, this includes the default files opened for the DOS standard input, standard output, standard error, auxiliary, and printer devices. DOS assigns the file handle values zero through four, respectively, to these devices. If a parent process closes one of these file handles and then reassigns the handle with a Force Duplicate File Handle call.

Note that the DOS EXEC call does not process the I/O redirection operators ("<", and ">", and "|"). If you want to redirect the standard I/O of a child process, you must do this before loading and executing the child process. To redirect one of the five standard I/O devices, you should do the following steps:

1) Duplicate the file handle you want to redirect (e.g., to redirect the standard output, duplicate file handle one).

2) Close the affected file (e.g., file handle one for standard output).

3) Open a file using the standard DOS Create or CreateNew calls.

4) Use the Force Duplicate File Handle call to copy the new file handle to file handle one.

5) Run the child process.

6) On return from the child, close the file.

7) Copy the file handle you duplicated in step one back to the standard output file handle using the Force Duplicate Handle function.

This technique looks like it would be perfect for redirecting printer or serial port I/O. Unfortunately, many programs bypass DOS when sending data to the printer and use the BIOS call or, worse yet, go directly to the hardware. Almost no software bothers with DOS' serial port support - it truly is that bad. However, most programs do call DOS to input or output characters on the standard input, output, and error devices. The following code demonstrates how to redirect the output of a child process to a file.




; REDIRECT.ASM -Demonstrates how to redirect I/O for a child process.
; This particular program invokes COMMAND.COM to execute
; a DIR command, when is sent to the specified output file.

                include stdlib.a
                includelib      stdlib.lib

dseg            segment para public 'data'

OrigOutHandle   word    ?                       ;Holds copy of STDOUT handle.
FileHandle      word    ?                       ;File I/O handle.
FileName        byte    "dirctry.txt",0         ;Filename for output data.

; MS-DOS EXEC structure.

ExecStruct      word    0                       ;Use parent's Environment blk.
                dword   CmdLine                 ;For the cmd ln parms.
                dword   DfltFCB
                dword   DfltFCB

DfltFCB         byte    3," ",0,0,0,0,0
CmdLine         byte    7, " /c DIR", 0dh       ;Do a directory command.
PgmName         dword   PgmNameStr              ;Points at pgm name.
PgmNameStr      byte    "c:\command.com",0
dseg            ends

cseg            segment para public 'code'
                assume  cs:cseg, ds:dseg


Main            proc
                mov     ax, dseg                ;Get ptr to vars segment
                mov     ds, ax
                MemInit                         ;Start the memory mgr.

; Free up some memory for COMMAND.COM:

                mov     ah, 62h                 ;Get our PSP value
                int     21h
                mov     es, bx
                mov     ax, zzzzzzseg           ;Compute size of
                sub     ax, bx                  ; resident run code.
                mov     bx, ax
                mov     ah, 4ah                 ;Release unused memory.
                int     21h

; Save original output file handle.

                mov     bx, 1                   ;Std out is file handle 1.
                mov     ah, 45h                 ;Duplicate the file handle.
                int     21h
                mov OrigOutHandle, ax           ;Save duplicate handle.

; Open the output file:

                mov     ah, 3ch                 ;Create file.
                mov     cx, 0                   ;Normal attributes.
                lea     dx, FileName
                int     21h
                mov     FileHandle, ax          ;Save opened file handle.

; Force the standard output to send its output to this file.
; Do this by forcing the file's handle onto file handle #1 (stdout).

                mov     ah, 46h                 ;Force dup file handle
                mov     cx, 1                   ;Existing handle to change.
                mov     bx, FileHandle          ;New file handle to use.
                int     21h

; Print the first line to the file:

                print
                byte    "Redirected directory listing:",cr,lf,0

; Okay, execute the DOS DIR command (that is, execute COMMAND.COM with
; the command line parameter "/c DIR").

                mov     bx, seg ExecStruct
                mov     es, bx
                mov     bx, offset ExecStruct ;Ptr to program record.
                lds     dx, PgmName
                mov     ax, 4b00h               ;Exec pgm
                int     21h

                mov     bx, sseg                ;Reset the stack on return.
                mov     ss, ax
                mov     sp, offset EndStk
                mov     bx, seg dseg
                mov     ds, bx

; Okay, close the output file and switch standard output back to the
; console.

                mov     ah, 3eh                 ;Close output file.
                mov     bx, FileHandle
                int     21h

                mov     ah, 46h                 ;Force duplicate handle
                mov     cx, 1                   ;StdOut
                mov     bx, OrigOutHandle       ;Restore previous handle.
                int     21h

; Return control to MS-DOS

Quit:           ExitPgm
Main            endp
cseg            ends

sseg            segment para stack 'stack'
                dw      128 dup (0)
endstk          dw      ?
sseg            ends

zzzzzzseg       segment para public 'zzzzzzseg'
Heap            db      200h dup (?)
zzzzzzseg       ends
                end     Main
19.1.4 - Exception Handling in DOS: Traps
19.1.5 - Redirection of I/O for Child Processes


Art of Assembly: Chapter Nineteen - 29 SEP 1996

[Chapter Nineteen][Previous] [Next] [Art of Assembly][Randall Hyde]



Number of Web Site Hits since Jan 1, 2000: