Листинг A-7. Полезные макрокоманды (STDMAC.INC):
----------------------------------------------------------------
; - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Файл включения макроопределений
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Стандартные равенства:
;
TRUE EQU 0FFFFh ; "истина"
FALSE EQU 0 ; "ложь"
;
; Cтандартные непечатаемые символы
NUL EQU 00000000b ; нуль
BEL EQU 00000111b ; "звонок"
BS EQU 00001000b ; возврат на символ с его стиранием
HT EQU 00001001b ; горизонтальная табуляция
LF EQU 00001010b ; перевод строки
FF EQU 00001100b ; перевод страницы
CR EQU 00001101b ; возврат каретки
SUBST EQU 00011010b ; подстановка
ESCAPE EQU 00011011b ; переход
SPACE EQU 00100000b ; пробел
COLON EQU 00111010b ; двоеточие
SCOLON EQU 00111011b ; точка с запятой
;
; Pасширенные символы (фирмы "ИБМ"):
SLINE EQU 11000100b ; горизонтальная строка
;
;- - - - - - - - - - - - - - - - - - - - - - -
..XLIST ; запретить распечатку макроопределений
;;.LALL ї_ї. ; распечатка всего
;;
;;
;;** @MODEL ********* Макроопределения общего назначения **
;; Установка сегментов согласно модели памяти.
;; Это макроопределение эмулирует управляющую команду
;; 5.Х.МОDEL макроассемблера MASM для использования с
;; более ранними версиями MASM.
IF1 ;; Ассемблирование только в процессе прохода 1
@Model MACRO memory_model,code_name,stack_size
;; ПРИМЕЧAHИЕ: "имя-программы" используется только
;; со средними, большими, а также с очень большими
;; моделями памяти
IFNB ;; модель памяти была указана?
;;
IF memory_model EQ 0
@TinyModel stack_size
ELSE
IF memory_model EQ 1
@SmallModel stack_size
ELSE
IF memory_model EQ 2
@MediumModel code_name,stack_size
ELSE
IF memory_model EQ 3
@CompactModel stack_size
ELSE
IF memory-model EQ 4
@ LargeModel code_name,stack_size
ELSE
IF memory_model EQ 5
@Large_Model code_name,stack_size
ELSE
.ERR
%0UT @Model macro: неизвестная модель памяти
ENDIF;; конец проверки очень большой модели
ENDIF;; конец проверки большой модели
ENDIF;; конец проверки компактной модели
ENDIF;; конец проверки средней модели
ENDIF;; конец проверки малой модели
ENDIF;; конец проверки очень малой модели
;;
ELSE ;; модель памяти не была указана
.ERR ;; завершить сообщением об ошибке
%0UT @MODEL macro error: модель памяти не указана
ENDIF ;; конец проверки параметров модели - памяти
;;
ENDM ;; конец макроопределения
;;
ENDIF ;; конец обработки прохода
;;
;;** @Tiny ************ Макрокоманды общего назначения **
;; (Эта управляющая макрокоманда вызывается через @Model 0.
;; Эта управляющая макрокоманда также может вызываться
;; непосредственно).
;; Отметим, что эта макрокоманда, в отличие от других мак-
;; рокоманд памяти-модели, не использует макрокоманду
;; @Stack, поскольку другие стеки в .COM - программах дол-
;; жны быть описаны в конце данной программы. Для опреде-
;; ления других стеков в .COM-программах выполните макро-
;; команду @Stack в соответствующем месте исходного текста
;; программы.
IF1 ;; Ассемблировать только в процессе прохода 1
@TinyModel MACRO
MEMODEL = 0
_TEXT SEGMENT BYTE PUBLIC 'CODE' ; сегмент программы
_TEXT ENDS
;; Назначить физические сегменты
ASSUME cs:_TEXT,ds:_TEXT,ss:_TEXT, es:_TEXT
;;- - - - - - - - - - - - - - - - - - - - - - -
;; Вставьте вручную следующий текст программы после
;; @Model 0:
;;
;; _TEXT SEGMENT
;; main PROС near ;; entry: ORG 0100h ;; jmp Start ;; ;
вставьте данные здесь, если требуется ;; start: ;; ;
вставьте текст программы здесь ;; main ENDP ;; ; вставьте
стандартные программы здесь ;; ; вставьте дополнительный
стек здесь ;; ; вставьте данные в конце, если требуется
;; _TEXT ENDS ;;
;;- - - - - - - - - - - - - - - - - - - - - - - - - - -
ENDM ;; конец макроопределения
ENDIF ;; конец обработки прохода
;;** @Small ************ Mакрокоманды общего назначения **
;; Управляющая макрокоманда для установки Малой (SMALL)
;; модели памяти.
;; (Эта макрокоманда вызывается через "@Model Small".
;; Эта макрокоманда может быть вызвана также
;; непосредственно.)
IF1 ;; Ассемблирование только в процессе прохода 1
@SmallModel MACRO stack_size
MEMODEL = 1
_TEXT SEGMENT BYTE PUBLICK 'CODE' ; сегмент программы
_TEXT ENDS
_DATA SEGMENT WORD PUBLIC 'DATA' ; сегмент данных
; (DGROUP)
_DATA ENDS
CONST SEGMENT WORD PUBLIC 'CONST' ; сегмент констант
CONST ENDS ; (DGROUP)
_BSS SEGMENT WORD PUBLIC 'BSS' ; сегмент непроинициа-
_BSS ENDS ; лизированных данных
; (DGROUP)
STACK SEGMENT PARA STACK 'STACK' ; сегмент стека
; (DGROUP)
STACK ENDS
;;
IFNB
@Stack stack_size
;;
ENDIF ;; конец обработки прохода
;;
DGROUP GROUP _DATA,CONST,_BSS,STACK ; группирование
; сегментов данных
;;
;; Назначить физические сегменты:
ASSUME cs:_TEXT, ds:DGROUP, ss:DGROUP, es:DGROUP
;;
ENDM ;; конец макроопределения
ENDIF ;; конец обработки прохода
;;
;;** @Medium ******** Макрокоманды общего назначения **
;; Управляющая макрокоманда для установки средней модели
;; памяти. (Эта макрокоманда вызывается через "@Model
;; medium". Эта макрокоманда может быть вызвана также
;; непосредственно.)
IF1 ;; Ассемблировать только в процессе прохода 1
@MediumModel MACRO code_name,stack_size
MEMODEL = 2
code_name_TEXT SEGMENT BYTE PUBLIC 'CODE' ;поименованный
; сегмент программы
code_name_TEXT ENDS ;
_DATA SEGMENT WORD PUBLIC 'DATA' ; сегмент данных
_DATA ENDS; (DGROUP)
CONST SEGMENT WORD PUBLIC 'CONST' ; сегмент констант
CONST ENDS; (DGROUP)
_BSS SEGMENT WORD PUBLIC 'BSS' ; сегмент непроинициа-
_BSS ENDS ; лизированных данных
; (DGROUP)
STACK SEGMENT PARA STACK 'STACK' ; сегмент стека
STACK ENDS; (DGROUP)
;;
IFNB
@Stack stack_size
ENDIF
;;
DGROUP GROUP _DATA,CONST,_BSS,STACK ; группирование
; сегмента данных
;;
;; Hазначить физические сегменты
ASSUME cs:_TEXT, ds:DGROUP, ss:DGROUP, es:DGROUP
;;
ENDM ;; конец макроопределения
ENDIF ;; конец обработки прохода
;;
;;** @COMPACT ****** Mакрокоманды общего назначения **
;; Управляющая макрокоманда для установки компактной
;; (COMPACT) модели памяти. (Эта макрокоманда вызывается
;; через "@Model compact". Эта макрокоманда может быть
;; вызвана также непосредственно.)
IF1 ;; Ассемблировать только в процессе прохода 1
@CompactModel MACRO stack_size
MEMODEL = 3
_TEXT SEGMENT BYTE PUBLIC 'CODE' ;сегмент текста программы
_TEXT ENDS
FAR_DATA SEGMENT PARA 'FAR_DATA' ; личный далекий сегмент
FAR_DATA ENDS ; данных (DGROUP)
FAR_BSS SEGMENT PARA 'FAR_BSS' ; личный далекий непро-
FAR_BSS ENDS ; инициализированный сег-
; мент данных (DGROUP)
_DATA SEGMENT WORD PUBLICK 'DATA' ; сегмент данных
_DATA ENDS ; (DGROUP)
CONST SEGMENT WORD PUBLIBC 'CONST' ; сегмент констант
CONST ENDS ; (DGROUP)
_BSS SEGMENT WORD PUBLIC 'BSS' ; сегмент непроинициа-
_BSS ENDS; лизированных данных
; (DGROUP)
STACK SEGMENT PARA STACK 'STACK' ; сегмент стека
STACK ENDS; (DGROUP)
;;
IFNB
@Stack stack_size
ENDIF
;;
DGROUP GROUP _DATA,CONST,_BSS,STACK ; группирование
; сегментов данных
;;
;; Назначить физические сегменты:
ASSUME cs:_TEXT,ds:DGROUP, ss:DGROUP,es:DGROUP
;;
ENDM ;; конец макроопределения
ENDIF ;; конец обработки прохода
;;
;;** @Large ***************** Mакрокоманды общего назначения **
;; Управляющая макрокоманда для установки большой (LARGE)
;; модели памяти. (Эта макрокоманда вызывается
;; через "@Model Large". Эта макрокоманда может быть
;; вызвана также непосредственно.)
IF1 ;; Ассемблировать только в процессе прохода 1
@LargeModel MACRO code_name,stack_size
MEMODEL = 4
code_name_TEXT SEGMENT BYTE PUBLIC 'CODE' ; поименованный
code_name_TEXT ENDS ; сегмент программы
FAR_DATA SEGMENT PARA 'FAR_DATA' ; личный далекий сегмент
FAR_DATA ENDS ; данных (DGROUP)
FAR_BSS SEGMENT PARA 'FAR_BSS' ; личный далекий непро-
FAR_BSS ENDS ; инициализированный сег-
; мент данных (DGROUP)
_DATA SEGMENT WORD PUBLIC 'DATA' ; сегмент данных
_DATA ENDS ; (DGROUP)
CONST SEGMENT WORD PUBLIC 'CONST' ; сегмент констант
CONST ENDS ; (DGROUP)
_BSS SEGMENT WORD PUBLIC 'BSS' ; сегмент непроинициа-
_BSS ENDS; лизированных данных
; (DGROUP)
STACK SEGMENT PARA STACK 'STACK' ; сегмент стека
STACK ENDS ; (DGROUP)
;;
IFNB
@Stack stack_size
ENDIF
;;
DGROUP GROUP _DATA,CONST,_BSS,STACK ; группирование
; сегмента данных
;;
;; Назначить физические сегменты
ASSUME cs:_TEXT,ds:DGROUP, ss:DGROUP,es:DGROUP
;;
ENDM ;; конец макроопределения
ENDIF ;; конец обработки прохода
;;
;;** @HUGE ************* Mакрокоманды общего назначения **
;; Управляющая макрокоманда для установки очень большой
;; (HUGE) модели памяти. (Эта макрокоманда вызывается
;; через "@Model huge". Эта макрокоманда может быть
;; вызвана также непосредственно.)
;; Oчень большая (HUGE) модель памяти в настоящее время
;; устанавливается так же как и Большая (LARGE) модель
;; памяти.
IF1 ;; Ассемблировать только в процессе прохода 1
@HugeModel MACRO code_name,stack_size
MEMODAL = 5
@LargeModel code_name,stack_size
ENDM ;; конец макроопределения
ENDIF ;; конец обработки прохода
;;
;;** @Stack ************* Mакрокоманды общего назначения **
;; Управляющая макрокоманда для установки размера стека
IF1 ;; Ассемблировать только в процессе прохода 1
@Stack MACRO stack_size,prog_type
;;
IFB ;; если параметр типа программы пустой
IF MEMODEL EQ 0
PROGTYPE = 0
ELSE
IF MEMODEL EQ 1
PROGTYPE = 1
ELSE
IF MEMODEL EQ 2
PROGTYPE = 1
ELSE
IF MEMODEL EQ 4
PROGTYPE = 1
ELSE
IF MEMODEL EQ 5
PROGTYPE = 1
ELSE
.ERR
%OUT @Stack macro: модель памяти
%OUT или тип программы не были установлены
ENDIF;; конец проверки очень большой модели
ENDIF ;; конец проверки большой модели
ENDIF ;; конец проверки компактной модели
ENDIF ;; конец проверки средней модели
ENDIF ;; конец проверки малой модели
ENDIF ;; конец проверки очень маленькой модели
ELSE ;; параметр типа программы был указан
IF prog_type EQ 0 ;; установка программы типа .COM
PROGTYPE = 0
ELSE
IF prog_type EQ 1
PROGTYPE = 1
ELSE
.ERR ;; выход с сообщением об ошибке
%OUT @Stack macro: указан некорректный тип программы
ENDIF ;; конец проверки типа .EXE
ENDIF ;; конец проверки типа .COM
ENDIF ;; конец проверки параметра "тип-программы"
;;
IFNB
;;
IF PROGTYPE EQ 0
; Дополнительный стек. BHИМAHИЕ - вы должны ис-
; пользовать функцию 4h для завершения данной
; программы, если вы используете локальный стек.
db stack_size DUP ('стек ')
top_of_stack EQU $
ELSE ;; тип программы - .EXE
STACK SEGMENT
db stack_size DUP ('стек ')
STACK ENDS
ENDIF ;; конец проверки PROGTYPE
;;
ELSE ;; параметр "размер-стека" не был указан
;;
IF PROGTYPE EQ 0
; Дополнительный стек. ВНИМАНИЕ - вы должны исполь-
; зовать функцию 4h для завершения данной программы
; в случае использования локального стека !
db 32 DUP ('стек ')
top_of_stack EQU $
ELSE ;; тип программы - .EXE
STACK SEGMENT
db 32 DUP ('стек ')
STACK ENDS
ENDIF ;; конец проверки PROGTYPE
ENDIF ;; конец проверки "размера стека"
;;
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @SwapNewStack ******** Mакрокоманды общего назначения **
;; Переключить стек на новый стек
IF1 ;; Ассемблировать только в процессе прохода 1
@SwapNewStack MACRO tos
LOCAL bypass
;;
jmp bypass ;; пропустить область данных
old_stk_seg dw ?;; пространство для
;; сегмента стека вызывающей макрокоманды
old_stk_ptr dw ?;; пространство для
; указателя стека вызывающей макрокоманды
new_stk_seg dw ?;; пространство для
;; нового сегмента стека
new_stk_ptr dw offset tos ;; пространство для
;; нового указателя стека
;;
bypass:
mov cs:new_stk_seg,cs ;; установить сегмент
;; нового стека
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 ; считать с клавиатуры без эхо
@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 ;; конец выполнения прохода
;;
;;** @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 ;; установить локальную метку
;;
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
;;
IFNB ;; тип вывода указан?
;;
If type EQ 10;; десятичное преобразование
;; указано?
IFNDEF EXT_BIN2DEC ;; было определеноEXT_BIN2DEC?
EXTRN bin2dec:NEAR ;; нет, вставьте определение
;; EXTRN
EXT_BIN2DEC EQU 0 ;; и только раз установите
;; равенство
ENDIF
;;
ELSE
;;
IF type EQ 16 ;; шестнадцатиричное
;; преобразование указано?
IFNDEF EXT_BIN2HEX ;; было определено EXT_BIN2HEX?
EXTRN bin2hex:NEAR ;; нет, вставьте определение
EXT_BIN2HEX EQU 0 ;; EXTRN и только раз установите
;; равенство
ENDIF
;;
ELSE
;;
.ERR
%OUT @DisNum Macro: указан "type" запрещенный "тип"
ENDIF ;; окончить проверку для шестнадца-
;; тиричного преобразования
;;
ENDIF ;; окончить проверку для десятичного преобразования
;;
ELSE ;; в противном случае, параметр пустой
;;
.ЕRR ;; завершить выполнение сообщением об ошибке
%OUT @DisNum macro: "type" параметр не указан
ENDIF ;; окончить проверку пустого параметра
;; Oкoнчить проверку требуемых параметров
;;
;; Hачать вставку программы
push ax ;; сохранить содержимое регистров
push cx
push dx
;;
mov ax,number ;; поместить число в AX
;;
IFNB ;; аргумент "разряды" указан?
mov ch,digits ;; да, записать значение в CH
ELSE ;; в противном случае, по умолчанию
mov ch,1 ;; отобразить по крайней мере 1 разряд
ENDIF
;;
IFNB ;; аргумент "знак" указан?
mov dx,sign ;; да, поэтому поместить его в DX
ELSE ;; в противном случае, по умолчанию знак
mov dx,0 ;; будет отсутствовать
ENDIF
;;
If type EQ 10;; десятичное преобразование указано?
call bin2dec
ELSE
IF type EQ 16 ;; шестнадцатиричное преобразование
;; указано?
call bin2hex
ENDIF ;; конец проверки по основанию 16
ENDIF ;; конец проверки по основанию 10
;;
pop dx ;; восстановить содержимое регистров
pop cx
pop ax
;;
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;
;;** @GetDate ********** Mакрокоманды общего назначения **
;; Получить системную дату
IF1 ;; Ассемблировать только в процессе прохода 1
@GetDate MACRO
mov ah,2Ah ;; загрузить номер функции
@DosCall ;; вызвать MS-DOS
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @GetTime ********** Mакрокоманды общего назначения **
;; Получить системное время
IF1 ;; Ассемблировать только в процессе прохода 1
@GetTime MACRO
mov ah,2Ch ;; загрузить номер функции
@DosCall ;; вызвать MS-DOS
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @DiskRead ******** Mакрокоманды общего назначения **
;; Считать логический сектор(а)
IF1 ;; Ассемблировать только в процессе прохода 1
@DiskRead MACRO
int 25h ;; обработать абсолютное прерывание
;; по чтению диска
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @DiskWrite ******* Mакрокоманды общего назначения **
;; Записать в логический сектор(а)
IF1 ;; Ассемблировать только в процессе прохода 1
@DiskWrite MACRO
int 26h ;; обработать машинное прерывание
;; по записи на диск
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @GetDOSVersion **** Mакрокоманды общего назначения **
;; Получить номер версии операционной системы MS-DOS
IF1 ;; Ассемблировать только в процессе прохода 1
@GetDOSVersion MACRO
push bx ;; сохранить содержимое
;; уничтоженных регистров
push cx
mov ah,30h ;; загрузить номер функции
@DosCall;; вызвать MS-DOS
pop cx ;; восстановить содержимое регистров
pop bx
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @GetDOSVer ******* Mакрокоманды общего назначения **
;; Получить номер версии операционной системы MS-DOS
IF1 ;; Ассемблировать только в процессе прохода 1
@GetDOSVer MACRO
IFNDEF EXT_GDOSV ;; символ определен?
EXTRN GETDOSV:NEAR ;; нет, вставить команду EXTRN
;; только один раз
EXT_GDOSV EQU 0 ;; и только раз определить
;; равенство
ENDIF;; (две верхние строки не
;; должны вставляться в
;; последующие вызовы
;; макроопределения)
call dosver ;; вызвать библиотечную
;; стандартную программу
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @DisDOSVer ********* Mакрокоманды общего назначения **
;; Получить и отобразить номер версии DOS
IF1 ;; Ассемблировать только в процессе прохода 1
@DisDOSVer MACRO
IFNDEF EXT_DDOSV ;; символ определен?
EXTRN DOSV2CON:NEAR ;; нет, вставить команду EXTRN
;; только один раз
EXT_DDOSV EQU 0 ;; и только раз определить
;; равенство
ENDIF;; (две верхние строки не
;; должны вставляться в
;; последующие вызовы
;; макроопределения)
call dosv2con ;; вызвать библиотечную
;; стандартную программу
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @ChangeСase ******* Mакрокоманды общего назначения **
;; Изменить регистр клавиатуры для символа
IF1 ;; Bыполнять только в процессе прохода 1
@ChangeCase MACRO char,type
IFB ;; символ, подлежащий преобразованию,
;; указан ?
.ERR ;; нет, сгенерировать и
;; вывести сообщение об ошибке
%OUT @ChangeCase macro: "char" параметр не определен !
ELSE ;; в противном случае
mov al,char ;; загрузите символ в AL
ENDIF
;;
IFB ;; тип преобразования указан?
mov ah,0 ;; нет, поэтому загрузить 0 в AH
ELSE
mov ah,type ;; загрузить тип преобразования в AH
ENDIF
;;
IFNDEF EXT_CHGCASE ;; символ EXT_CHGCASE определен?
EXTRN CHGCASE:NEAR ;; нет, вставить EXTRN только раз
EXT_CHGCASE EQU 0 ;; и только раз определить равенство
ENDIF ;; (две верхние строки не должны вставляться в
;; последующие вызовы данной макрокоманды)
;;
call chgcase ;; вызвать библиотечную процедуру
;; изменения регистра клавиатуры
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @case ************* Mакрокоманды общего назначения **
;; Mакрокоманда CASE языка ассемблера
@Case MACRO key,case_list,jmp_labels
??tmp_1 = 0
IRP match,<&case_list> ;; упорядочить регистры
??tmp_1 = ??tmp_1 + 1 ;; установить номер индекса
cmp key,&&match ;; регистр соответствует?
??tmp_2 = 0
IRP retl,<&jmp_labels> ;; упорядочить переходы
??tmp_2 = ??tmp_2 + 1 ;; до тех пор, пока индекс
;; не будет соответствовать
IF (??tmp_1 EQ ??tmp_2)
je &&&retl ;; да !
EXITM
ENDIF ;; конец проверки условия
ENDM ;; конец второго блока IRP
ENDM ;; конец первого блока IRP
ENDM ;; конец макроопределения
;;
;;
;;*****************************************************
;; Используйте макрокоманды @PushAll и @PopAll вместо ко-
;; манд PUSHA и POPA, поддерживаемых процессором
;; 80186/80188/80286/80386 для обеспечения совместимости
;; с процессорами 8086/8088.
;;
;;** @PushAll ********** Mакрокоманды общего назначения **
;; Поместить в стек содержимого всех регистров
IF1 ;; Выполнять только в процессе прохода 1
@PushAll MACRО ;; сохранить содержимое всех регистров в стеке
push ax
push bx
push cx
push dx
push dp
push di
push si
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @PopAll *********** Mакрокоманды общего назначения **
;; Снять со стека содержимое всех регистров
IF1 ;; Выполнять только в процессе прохода 1
@PopAll MACRO ;; восстановить содержимое всех
;; регистров из стеке
pop si
pop di
pop dp
pop dx
pop cx
pop bx
pop ax
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;** @ExiToDos ********* Mакрокоманды общего назначения **
;; Завершить процесс с необязательными установками
;; значений переменной ERRORLEVEL
IF1 ;; Выполнять только в процессе прохода 1
@ExiToDOS MACRO errorcode
IFB ;; код ошибки был указан?
mov ax,4C00h ;; нет, загрузить функцию и значение
;; переменной ERRORLEVEL = "0" в AX
ELSE ;; в противном случае
mov ah,4Ch ;; загрузить функцию и значение
mov al,errorcode ;; переменной ERRORLEVEL отдельно
ENDIF
;;
@DosCall ;; вызвать MS-DOS
ENDM ;; конец макроопределения
ENDIF ;; конец выполнения прохода
;;
;;********************************************************
;; Конец макроопределений
;;********************************************************
.LIST ; восстановить выдачу листингов в нормальном виде
;; Kонец файла включения макроопределений
----------------------------------------------------------------
|