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.
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