How do I read a character from standard input in DOS for redirection to work?

I am currently writing a DOS program. In this program, I am using the 21 / AH = 01 service to read a character from standard input. However, it appears that when redirecting stdin from a file, EOF detection is not working as expected. I wrote this sample program in nasm syntax to illustrate the problem:

    org 0x100

    ; read characters and sum them up
main:   xor bx,bx

.1: mov ah,1
    int 0x21
    xor ah,ah
    add bx,ax
    cmp al,0x1a       ; eof reached?
    jnz .1

    mov cx,4
.2: mov si,bx
    shr si,12
    mov dl,[hextab+si] ; convert to hex
    mov ah,2
    int 0x21
    shl bx,4
    loop .2

    ret

hextab: db '0123456789ABCDEF'

      

When I redirect standard input from a file, the program hangs, unless that file contains ^ Z. I was under the impression that EOF was flagged by the 21 / AH = 01 service returning ^ Z to DOS, however, this does not seem to be the case.

How can I read a character from standard input in DOS in a way that works with redirected stdin in such a way that the character is reflected on the screen if the input is not redirected and that I can detect an EOF condition? Ideally I would like to have something that behaves like a function getchar()

.

+3


source to share


1 answer


Instead, you must use the "MS-DOS" read function. In general, you want to avoid the old deprecated MS-DOS 1.x API functions. Output functions (AH = 1, AH = 9) are usually fine, but most of the rest should not be used unless you need your program to run under MS-DOS 1. MS-DOS 2.0 introduced a completely new set of Unix-like file functions that for the most part work the same as the equivalent Unix function. Thus, in this case, the MS-DOS read function, like the Unix system call read

, takes three parameters: a file descriptor, a buffer address, and the number of characters to read. As on Unix, the file descriptor is 0 for standard input, 1 for standard output, and 2 for standard error.

So, you can rewrite your example to use MS-DOS read (AH = 3Fh) and write (AH = 40h) the following functions:



    ORG 0x100

main:
    xor di, di
    mov bp, buf
    mov dx, bp
    mov cx, 1

loopchar:
    mov ah, 0x3f
    int 21h
    jc  error
    dec ax
    js  eof           ; EOF reached?
    cmp BYTE [bp], 0x1a
    je  eof
    add di, [bp]
    jmp loopchar

eof:
    inc cx
    mov ax, di
    mov al, ah
    call printhex1
    jc  error
    xchg ax, di

printhex1:
    mov bx, hextab
    aam 16
    xlat
    mov [bp + 1], al
    mov al, ah
    xlat    
    mov [bp], al
    mov bx, 1
    mov ah, 0x40
    int 21h

error:
    ret

buf db  0, 0

hextab: db '0123456789ABCDEF'

      

+6


source







All Articles