Я изучаю макросы на ассемблере и где-то застрял. Я пытался прочитать и вывести только один символ следующим образом в макрофайле. (Я хочу научиться использовать функции 01h и 02h, потому что уже знаю, как использовать функции 09h и 0Ah):

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

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

В файле .ASM я называю их следующим образом:

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

Не получается, и я не могу понять, почему. Любые идеи будут полезны.

opia

Ответы (2)

Структура EMPTYCHAR в вашей программе подходит для DOS.BufferedInput функции 0Ah, которую, как вы говорите, вы не хотите использовать (на этот раз). Однако она не подходит для функций, которые вы собираетесь использовать сегодня.

Макросу READCHAR вообще не нужен аргумент. Функция 01h DOS.GetCharacter вернет код ASCII для нажатой клавиши в регистре AL.
С другой стороны, макрос PRINTCHAR требует аргумента, чтобы быть полезным. Ведь функция 02h DOS.PrintCharacter ожидает получить ASCII-код в регистре DL.

Вот как должны быть написаны ваши макросы:

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

и как вы можете их использовать:

.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

Указание параметра для макроса PRINTCHAR не ограничивается только регистром AL. Вы также можете указать непосредственное число, как в PRINTCHAR 13 (для вывода возврата каретки) и PRINTCHAR "-" (для вывода дефиса), или даже ссылку на память, как в PRINTCHAR [Char].

Заметим также, что иногда может быть полезно сохранить некоторые регистры, как показано ниже:

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

INT 21H / AH = 01H помещает считанный символ в регистр AL, но INT 21H / AH = 02H ожидает, что символ будет записан в регистр DL.

Попробуйте MOV DL, AL между двумя вызовами.

Заметьте, что в данном случае ваш буфер EMPTYCHAR вообще ничего не делает; эти вызовы не используют буфер памяти, и более того, ваши макросы даже не используют свои параметры INPUT2. Я не совсем понимаю, что вы хотели этим сделать; если вы хотите поместить символ в память, вам придется хранить его там самостоятельно.

2022 WebDevInsider