;; нового стека
mov cs:old_stk_seg,ss ;; сохранить старые
;; значения стека
mov cs:old_stk_ptr,sp ;; сохранить старый
;; указатель стека
mov ss,cs:new_stk_seg ;; получить новые
;; значения стека
mov sp,cs:new_stk_ptr ;; получить новый
;; указатель стека
@PushAll ;; сохранить признаки и
;; содержимое всех регистров
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;**@SwapOldStack********** Mакрокоманды общего назначения **
;; Переключить с нового стека на исходный стек
@Popall ;; восстановить признаки и
;; содержимое всех регистров
mov ss,cs:old_stk_seg ;; восстановить старые
;; значения стека
mov sp,cs:old_stk_ptr
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @DosCall ************* Mакрокоманды общего назначения **
;; Bызвать функцию MS-DOS
IF1 ;; Ассемблировать только в процессе прохода 1
@DosCall MACRO
int 21h
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;**@DirConChar 10 ***** Mакрокоманды общего назначения **
@DirConCharIO MACRO ; проверить состояние клавиатуры
; и считать
push dx ; cохранить DX
mov dl,0FFh ; нет символа для вывода
mov ah,06h ;
@DosCall
pop dx ; восстановить DX
ENDM
;;
;;** @ReadCon_NoEcho **** Mакрокоманды общего назначения **
@ReadCon_NoEcho MACRO
mov ah,08h ; считать с клавиатуры без эхо
- П-19 -
@DosCall
ENDM
;;
;;** @ReadBuffInput ***** Mакрокоманды общего назначения **
@ReadBuffInput MACRO bufname ; считать буферизованный
; ввод с клавиатуры
mov dx,offset bufname
mov ah,0Ah
@DosCall
ENDM
;;
;;**DisChr ************** Mакрокоманды общего назначения **
;; Отобразить на экране символ
IF1 ;; Ассемблировать только в процессе прохода 1
@DisChr MACRO char
IFNB ;; аргумент символа был указан ?
;; да, поэтому вставить команду
push ax ;; сохранить используемые регистры
push dx
mov dl,char ;; загрузить символ
mov ah,02h ;; загрузить номер функции
@DosCall ;; вызвать MS-DOS
pop dx ;; восстановить содержимое регистров
pop ax
ELSE ;; в противном случае
.ERR ;; сгенерировать и вывести
;; сообщение об ошибке
%OUT @DisChr macro : "char" аргумент
не указывается
ENDIF
;;
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @DisStr ************** Mакрокоманды общего назначения **
;; Oтобразить на экране строку памяти с терминатором кон-
;; ца-строки по умолчанию "$" или с указанным терминатором.
;; (Bызовы внутренних макрокоманд @DisStr1 или @DisStr2.)
IF1 ;; Ассемблировать только в процессе прохода 1
@DisStr MACRO строка,терминатор
IFNB ;; параметр строки был указан?
;; да, поэтому
IFB ;; терминатор был указан?
;; нет, поэтому вставить команду по
;; умолчанию для терминатора "$"
@DisStr1 string
ELSE ;; в противном случае терминатор был указан
@DisStr2 string,terminator
ENDIF ;; конeц проверки "терминатора"
ELSE ;; в противном случае,"строка" не была указана
.ERR ;; сгенерировать и вывести сообщение об ошибке
%OUT @DisStr macro: "string" аргумент не
указывается
ENDIF
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
- П-20 -
;;
;;** @DisStr1 ********** Служебные макрокоманды *******
;; Вызваны макрокомандой @DisStr1 для отображения строки
;; памяти с терминатором конца-строки "$" по умолчанию.
IF1 ;; Ассемблировать только в процессе прохода 1
@DisStr1 MACRO string
push ax ;; сохранить используемые регистры
push dx
mov dx,offset ds:string ;; указать на строку
;; в памяти
mov ah,09h ;; загрузить номер функции
@DosCall ;; обратиться к MS-DOS
pop dx ;; сохранить регистры
pop ax
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;** @DisStr2 ************ Служебные макрокоманды *******
;; Вызваны макрокомандой @DisStr1 для отображения строки
;; памяти с указанным терминатором конца-строки.
IF1 ;; Ассемблировать только в процессе прохода 1
@DisStr2 MACRO string,terminator
LOCAL strloop,strloopdone ;; создать локальные метки
push si ;; сохранить регистры
push ax
push bx
push dx
xor bh,bh ;; очистить BX
mov bl,terminator ;; получить терминатор
mov si,offset string ;; указать на строку
xor dx,dx
strloop:
mov dl,byte ptr [si] ;; получить следующий символ
cmp dl,bl ;; это терминатор?
je strloopdone ;; да, мы сделали
mov ax,02h ;; загрузить функцию
;; вывода символов
@DosCall ;; и вызвать DOS
jnc si ;; указать на следующий символ
jmp short strloop ;; и повторить
strloopdone:
pop dx ;; восстановить содержимое регистров
pop bx
pop ax
pop si
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @TypeStr ********** Mакрокоманды общего назначения **
;; Отобразить ближайшую строку.
;; Примечание: "строка" должна быть представлена в кавычках
;; с тем, чтобы она обрабатывалась как один аргумент макро-
;; команды и чтобы гарантировать, что данные закодированы
;; корректно.
IF1 ;; Ассемблировать только в процессе прохода 1
@TypeStr MACRO string ;; определить и отобразить
;; строку
LOCAL TypeStrAddr ;; установить локальную метку
- П-21 -
;;
IF MEMODEL NE 0 ;; если не тип .COM
_TEXT ENDS ;; конец сегмента программы
_DATA SEGMENT ;; изменить на сегмент данных
ENDIF
TypeStrAddr DB string,'$' ;; определить строку в сегменте
;; данных
IF MEMODEL NE 0 ;; если не тип .COM
_DATA ENDS ;; конец сегмента данных
_TEXT SEGMENT ;; вернуться к сегменту программы
ENDIF
;;
@DisStr TypeStrAddr ;; отобразить строку
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @TypeStrCR ******** Mакрокоманды общего назначения **
;; Oтобразить ближайшую строку , завершаемую с
;; помощью GR/LF.
IF1 ;; Ассемблировать только в процессе прохода 1
;; "строка" должна быть представлена в кавычках с тем, чтобы
;; она обрабатывалась как один аргумент макрокоманды.
@TypeStrCR MACRO string
@TypeStr string ;; определить и отобразить строку
@NewLine ;; завершить с помощью GR/LF
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;**@NewLine *********** Mакрокоманды общего назначения **
;; Oтобразить символ возврата каретки и перевода строки.
IF1 ;; Ассемблировать только в процессе прохода 1
@NewLine MACRO
IFNDEF EXT_NEWLINE ;; символ EXT_NEWLINE
;; был определен?
EXTRN newLine:NEAR ;; нет, вставьте EXTRN
;; только один раз
EXT_NEWLINE EQU 0 ;; и опишите равенство
;; только один раз
ENDIF ;; верхние две строки не должны
;; в последующие вызовы макрокоманд вставляться
call newLine ;; вызвать процедуру NEWLINE
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;**@DisNum ************ Mакрокоманды общего назначения **
;; Отобразить двоичное число в десятичном или шестнадцати-
;; ричном виде кода ASCII.
IF1 ;; Ассемблировать только в процессе прохода 1
@DisNum MACRO number,type,digits,sign
;;
;; Проверьте сначала требуемые параметры
IFB ;; числовой параметр указан?
.ERR ;; нет, завершить обработку
;; сообщением об ошибке
%OUT @DisNum macro: "number" параметр не указан.
ENDIF
;;
- П-22 -
IFNB ;; тип вывода указан?