Using Interrupt 21h, Function 3Fh to Read the Keyboard

This article was previously published under Q113058
Retired KB Content Disclaimer
This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.
The "MS-DOS Programmer's Reference" (published by Microsoft Press) versions5 and 6, as well as other MS-DOS programming reference books, state thatInterrupt 21h, Function 0Ah (Buffer Keyboard Input) has been superseded by Function 3Fh (Read File or Device). Function 3Fh is more general purpose and easier to use for some programming tasks, but may cause some apparentlyunusual behavior when used to read from device 0 (stdin--the console orkeyboard).

Function 3Fh uses a system buffer when reading from a device and then transfers the desired number of characters into a memory buffer specifiedby the calling program. The buffer used by Function 3Fh is not the same asthat used by MS-DOS or by other functions that read from the keyboard(Functions 01h, 06h, 07h, 08h, 0Ah, and 0Ch). Function 3Fh moves charactersfrom the input buffer to the program supplied data area either until therequested number of characters have been read or, if reading from thekeyboard, until a carriage return is reached. When more characters thanrequested are entered from the keyboard, the requested number are returnedto the program, but the input buffer is not flushed. This may causesubsequent read operations to return with invalid or undesired data. Thiscan even occur between separate instances of program execution.

The sample shown below illustrates this, and shows how to clear the bufferby reading until a linefeed character has been found.
The sample prompts for input, reads up to 10 characters, and displays thecharacters read. If more than 10 characters are entered, only the first 10will be displayed. If the program is then executed a second time, theremaining characters (or the next 10, whichever is less) will beimmediately displayed. The prompt will be given but the program will notwait for input.

If the commented lines following the label clearbuf are added into theprogram, the input buffer will be cleared and the program will work asexpected. Note that the code to clear the buffer reads until it finds alinefeed character (0Ah) rather than a carriage return (0Dh).Experimentation shows that if the linefeed is left in the buffer, theprogram will wait for another carriage return after running the loop, andwill not read any data the next time it is run. Function 3Fh does notreturn the carriage return/linefeed (CR/LF) pair to the calling programwhen reading multiple bytes, but does return them when reading 1 byte at atime, and therefore both must be cleared as shown.

Also note that possible read and write errors are being ignored by thiscode. Refer to "MS-DOS Programmer's Reference" for information on possibleerrors and how to detect them.

The "MS-DOS Programmer's Reference" is available through Microsoft Press bycalling 1-(800)-MSPRESS.
"MS-DOS Programmer's Reference," Version 5, Microsoft Press, 1991. Page282.

"MS-DOS Programmer's Reference," Version 6, Microsoft Press, 1993. Pages278-9.

Sample Code

; Assemble options needed:  none.MODEL SMALL,C.STACK.DATA    mybuf BYTE 10 DUP (' ')    pstring BYTE 0Dh,0Ah,"enter data: "    ostring BYTE 0Dh,0Ah,"data entered: "    abyte BYTE ?.CODE    .STARTUP    ; prompt user    mov bx, 1  ; stdout    mov cx, LENGTHOF pstring    mov dx, SEG pstring    mov ds, dx    mov dx, OFFSET pstring    mov ah, 40h    INT 21h        ; ignore possible errors    ; read data    mov bx, 0  ; stdin    mov cx, LENGTHOF mybuf    mov dx, SEG mybuf    mov ds, dx    mov dx, OFFSET mybuf    mov ah, 3Fh    INT 21h        ; ignore possible errors    mov bx, 1  ; stdout    mov cx, LENGTHOF ostring    mov dx, SEG ostring    mov ds, dx    mov dx, OFFSET ostring    mov ah, 40h    INT 21h        ; ignore possible errors    mov bx, 1  ; stdout    mov cx, LENGTHOF mybuf    mov dx, SEG mybuf    mov ds, dx    mov dx, OFFSET mybuf    mov ah, 40h    INT 21h        ; ignore possible errors    ; clear buffer    mov bx, 0  ; stdin    mov cx, 1    mov dx, SEG abyte    mov ds, dx    mov dx, OFFSET abyte    mov ah, 3Fh    INT 21h    mov al, abyte    cmp al, 0Ah    jne clearbuf    .EXITEND				
kbinf 5.10 5.10a 6.00 6.00a 6.00b 6.10 6.10a masm assembly assembler DOS int

ID d'article : 113058 - Dernière mise à jour : 10/14/2003 22:00:18 - Révision : 1.1

Microsoft Macro Assembler 5.1 Standard Edition, Microsoft Macro Assembler 5.1a, Microsoft Macro Assembler 6.0 Standard Edition, Microsoft Macro Assembler 6.0a, Microsoft Macro Assembler 6.0b, Microsoft Macro Assembler 6.1 Standard Edition, Microsoft Macro Assembler 6.1a, Microsoft Macro Assembler 6.11 Standard Edition

  • KB113058