Under MS-DOS versions 2.0 and later, the preferred method for sending text to the display is to use handle-based Int 21H Function 40H (Write File or Device). When an application program receives control, MS-DOS has already assigned it handles for the standard output (1) and standard error (2) devices, and these handles can be used immediately. For example, the sequence at the top of the following page writes the message hello to the display using the standard output handle.
msg db 'hello' ; message to display
msg_len equ $-msg ; length of message
.
.
.
mov ah,40h ; function 40h = write file or device
mov bx,1 ; BX = standard output handle
mov cx,msg_len ; CX = message length
mov dx,seg msg ; DS:DX = address of message
mov ds,dx
mov dx,offset msg
int 21h ; transfer to MS-DOS
jc error ; jump if error detected
.
.
.
If there is no error, the function returns the carry flag cleared and the number of characters actually transferred in register AX. Unless a Ctrl-Z is embedded in the text or the standard output is redirected to a disk file and the disk is full, this number should equal the number of characters requested.
As in the case of keyboard input, the user's ability to specify command-line redirection parameters that are invisible to the application means that if you use the predefined standard output handle, you can't always be sure where your output is going. However, to ensure that your output actually goes to the display, you can use the predefined standard error handle, which is always opened to the CON (logical console) device and is not redirectable.
As an alternative to the standard output and standard error handles, you can bypass any output redirection and open a separate channel to CON, using the handle obtained from that open operation for character output. For example, the following code opens the console display for output and then writes the string hello to it:
fname db 'CON',0 ; name of CON device
handle dw 0 ; handle for CON device
msg db 'hello' ; message to display
msg_len equ $-msg ; length of message
.
.
.
mov ax,3d02h ; AH = function 3dh = open
; AL = mode = read/write
mov dx,seg fname ; DS:DX = device name
mov ds,dx
mov dx,offset fname
int 21h ; transfer to MS-DOS
jc error ; jump if open failed
mov handle,ax ; save handle for CON
.
.
.
mov ah,40h ; function 40h = write
mov cx,msg_len ; CX = message length
mov dx,seg msg ; DS:DX = address of message
mov ds,dx
mov dx,offset msg
mov bx,handle ; BX = CON device handle
int 21h ; transfer to MS-DOS
jc error ; jump if error detected
.
.
.
As with the keyboard input functions, MS-DOS also supports traditional display functions that are upwardly compatible from the corresponding CP/M output calls:
Int 21H Function 02H sends the character in the DL register to the standard output device. It is sensitive to Ctrl-C interrupts, and it handles carriage returns, linefeeds, bell codes, and backspaces appropriately.
Int 21H Function 06H transfers the character in the DL register to the standard output device, but it is not sensitive to Ctrl-C interrupts. You must take care when using this function, because it can also be used for input and for status requests.
Int 21H Function 09H sends a string to the standard output device. The string is terminated by the $ character.
With MS-DOS version 2 or later, these three traditional functions are converted internally to handle-based writes to the standard output and thus are susceptible to output redirection.
The sequence at the top of the following page sounds a warning beep by sending an ASCII bell code (07H) to the display driver using the traditional character-output call Int 21H Function 02H.
.
.
.
mov dl,7 ; 07h = ASCII bell code
mov ah,2 ; function 02h = display character
int 21h ; transfer to MS-DOS
.
.
.
The following sequence uses the traditional string-output call Int 21H Function 09H to display a string:
msg db 'hello$'
.
.
.
mov dx,seg msg ; DS:DX = message address
mov ds,dx
mov dx,offset msg
mov ah,9 ; function 09h = write string
int 21h ; transfer to MS-DOS
.
.
.
Note that MS-DOS detects the $ character as a terminator and does not display it on the screen.