1

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.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
opia
  • 65
  • 1
  • 7

2 Answers2

2

INT 21H / AH = 01H puts the character read into the AL register, but INT 21H / AH = 02H expects the character to be written in the DL register.

So try a MOV DL, AL in between the two calls.

Note that as it stands your EMPTYCHAR buffer is not doing anything at all; these calls don't use a memory buffer, and indeed your macros don't even use their INPUT2 parameters. I'm not sure what you were intending it to do; if you want to put the character into memory, you'll have to store it there yourself.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
1

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
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • thank you for your answer mate it helped me understand what I'm doing and what should be done! one extra question I have in mind tough: whenever I add a line between the read and print in asm file it fails( like this : readchar printstring line(line DB 0DH,0AH,'$') printchar) do you have any ideas for that? – opia Jan 06 '21 at 11:14
  • @opia If you literally write `printstring line(line DB 0DH,0AH,'$')`, it is not an allowed syntax. But assuming `line db 13,10,'$'` is placed somewhere outside of the execution path, and that you define your *printstring* macro as: `PRINTSTRING MACRO TheArg` `lea dx, TheArg` `mov ah, 09h` `int 21h` `ENDM`, invoking that macro will work if you do it like: `printstring [line]`. This is with surrounding square brackets so it is recognized as a memory reference. – Sep Roland Jan 06 '21 at 22:43
  • yes that line was in data segment. thanks for ending my strugglings buddy, literally...i owe you – opia Jan 08 '21 at 14:18