TSR Logs Assembler and Compiler Errors In File

If you use a PC to develop software for embedded systems, you probably still use good, old MS-DOS for most of your processing, because most compilers, assemblers, and linkers don't run under MS Windows.

If you're developing a sizable program, you probably use automated procedures such as batch files or "make" files to build and rebuild your target program. When you use batch files or make files, capturing the PC's screen output in a disk file is more convenient than sitting around, watching everything endlessly scroll by on the screen.

You can capture screen output by using the MS-DOS redirection feature, causing all MS-DOS console output to go to the disk file you specify.

However, DOS actually has two types of console output, known in DOS lingo as stdout and stderr. When you ask DOS to redirect screen output to a disk file, it only changes the destination of stdout's output.

The problem is that programs such as assemblers and compilers can send messages to the screen via either stdout or stderr. In general, programs should use stdout for ordinary output, such as status messages and nonfatal error messages, and stderr for catastrophic error messages such as disk failure, memory corrupted, etc. These distinctions make sense because if the program detects a catastrophic failure, you probably want immediate notification on the screen.

Unfortunately, not all programs follow this convention. Some programs send "good" messages to stdout and "bad" (though nonfatal) error messages to stderr (I guess that's what they thought stderr was for).

For example, I use a particular 68HC11 cross-assembler that sends the startup banner and termination message to stdout but sends all assembly-language syntax error messages to stderr. Only the start and finish messages are captured in the disk file while the assembly error messages scroll off the top of the screen. So when I use MS-DOS redirection to capture the output in a disk file, all assemblies look as though they worked fine, with no errors!

To get around this problem, the simple "terminate and stay resident" program (TSR) in the listing below, called STDERROR.ASM, sends all stderr output to stdout. If you don't use DOS redirection to capture screen output in a disk file, the STDERROR TSR has no apparent effect. However, it you use DOS redirection to capture screen output in a file, STDERROR causes stderr output to also go to the file.


main    segment para public 'CODE'
        assume cs:main, ds:main

        org      100h                   ; require for .COM file
start:  jmp      start1

old_vector  dd   ?                      ; save old DOS int 21 vector

        mov      ax, 0
        mov      es, ax
        les      bx, es:[21h * 4]        ; read the vector for DOS int 21
        mov      word ptr [old_vector], bx   ; save it so we can chain to it
        mov      word ptr [old_vector + 2], es
        mov      ax, 0
        mov      es, ax
        cli                               ; disable interrupts while we write
        mov      es:[21h * 4], offset isr ; chain our handler to DOS int 21
        mov      es:[(21h * 4) + 2], cs
        sti                               ; enable interrupts
        mov      ax, 3100h                ; function code to become resident
        mov      dx, last / 16 + 11h      ; reserve memory paragraphs for us
        int      21h                      ; return to DOS but remain resident

; This interrupt service routine is chained to the main DOS int 21 vector.

isr:    cmp      ah, 40h                  ; function code = write to file?
        jne      exit                     ; jump if no, don't do anything
        cmp      bx, 2                    ; handle = stderr?
        jne      exit                     ; jump if no, don't do anything
        dec      bx                       ; force handle to stdout
exit:   jmp      dword ptr cs:[old_vector] ; let DOS do its thing

last    equ      $ - start                ; how much memory we use

main    ends
        end      start

Computer Page   Home Page