Search code examples
assemblymacrosdosx86-16tasm

Macros to read and print a character in assembly


I'm learning macros in assembly and I'm stuck somewhere. I tried to read and print only one character as follows in macro file. (I want to learn how to use functions 01h and 02h because by now I know how to use functions 09h and 0Ah):

READCHAR MACRO INPUT2
MOV AH, 01H
INT 21H
ENDM

PRINTCHAR MACRO INPUT2
MOV AH, 02H
INT 21H
ENDM

I call them as follows in .ASM file:

.data
EMPTYCHAR DB 1, ?, 1 DUP (‘$’)
.code
READCHAR EMPTYCHAR 
PRINTCHAR EMPTYCHAR

It fails and I couldn't figure out why. Any ideas will be helpful.


Solution

  • The EMPTYCHAR structure in your program fits the DOS.BufferedInput function 0Ah that you say you don't want to use (this time). However it doesn't serve any purpose with the functions you intend to use today.

    The READCHAR macro doesn't need an argument at all. The DOS.GetCharacter function 01h will return the ASCII code for the pressed key in the AL register.
    On the other hand the PRINTCHAR macro does require an argument to be of any use. After all the DOS.PrintCharacter function 02h expects to receive an ASCII code in the DL register.

    This is how your macros should be written:

    READCHAR MACRO
      mov ah, 01h    ; DOS.GetCharacter
      int 21h        ; -> AL
    ENDM
    
    PRINTCHAR MACRO TheArg
      mov dl, TheArg
      mov ah, 02h    ; DOS.PrintCharacter
      int 21h
    ENDM
    

    and how you can use them:

    .data
    Char DB 0
    .code
    READCHAR         ; -> AL
    mov [Char], al   ; Only in case you desire to save a copy in memory, else strike this line!
    PRINTCHAR al
    

    Specifying the parameter for the PRINTCHAR macro is not limited to just the AL register. You could also supply an immediate number like in PRINTCHAR 13 (to output carriage return) and PRINTCHAR "-" (to output a hyphen), or even a memory reference like in PRINTCHAR [Char].

    Note also that sometimes it could be useful to preserve some register(s) like shown below:

    PRINTCHAR MACRO TheArg
      push dx
      mov  dl, TheArg
      mov  ah, 02h    ; DOS.PrintCharacter
      int  21h
      pop  dx
    ENDM