Например,
TYPE N = 1, если N - байт
TYPE N = 2, ecли N - слово
TYPE N = 4, ecли N - двойное слово
TYPE N = 8, если N - четверное слово
TYPE N = 10, если N - десятибайтовое слово (т.е. с плаваю-
щей точкой)
TYPE N = XX, если N - cтруктура длиной в хх байтов
TYPE N = FFFF,если N - "близкая" программная метка
TYPE N = FFFE,если N - "удаленная" программная метка
Следующее макро иллюстрирует использование директив TYPE и
.TYPE:
@FcnCall MACRO Fnctn,ParmList ;;список подпро-мм и парам-ов
IRP N, ;;неопределен.
повторение
BYTELENGTH = TYPE N ;;получить длину "проталкива-
;;емых" элементов в байтах
IF ((.TYPE N ) NE 22H) ;;N определено и зави-
;;симо от данных?
push N ;;если нет - предположить 16-битовый регистр ;;
ELSE ;;в противном случае предположить данные
IF (BYTELENGTH EQ 2) ;;тогда, если параметр 2-
;;байтовый,
push N ;;протолкнуть
ELSE ;;в противном случае
IF (BYTELENGTH EQ 1) ;;если параметр 1-байтовый,
;;предположить, что AX доступен
mov ah,0 ;;очистить верхнюю часть AX
mov al,N ;;сделать параметр словом
push ax ;;так, чтобы мы могли продвинуть его
ELSE ;;в противном случае
IF (BYTELENGTH EQ 4) ;;если параметр 4-байтовый
push word ptr N ;;продвинуть 1-ое и
push word ptr N + 2 ;;2-ое слово
ELSE ;;в противном случае
IF (BYTELENGTH EQ 8) ;;если параметр 8-байт.
push word ptr N ;;продвинуть 1-ое,
push word ptr N + 2 ;; 2-ое
push word ptr N + 4 ;; 3-ье и
push word ptr N + 6 ;; 4-ое слово
ELSE ;;в противном случае
IF (BYTELENGTH EQ 10) ;;если параметр
;;10-байтовый, продвинуть
- 1-56 -
push word ptr N ;; 1-ое
push word ptr N + 2 ;; 2-ое
push word ptr N + 4 ;; 3-ье
push word ptr N + 6 ;; 4-ое и
push word ptr N + 8 ;; 5-ое слово
ELSE
.ERR
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
call Fnctn
ENDM ;;конец IRP
ENDM ;;конец макро
Замечательным преимуществом данного макро является то, что мы
заранее не указываем количество параметров, которое хотим перес-
лать подпрограмме, до непосредственного обращения к ней. Мы можем
вызвать одну подпрограмму с тремя параметрами, а другую - с дву-
мя.
Например:
@FcnCall Fcn1,
@FcnCall Fcn2,
Для любого вызова подпрограммы мы можем иметь фактически неог-
раниченное число параметров.
В данном макро имеется много недостатков. Одним из этих недос-
татков является то, что мы не покрыли все возможные значения
BYTELENGTH, типа программных меток и структур; мы предположили,
что регистр AX доступен только для однобайтового параметра и т.д.
Для большинства этих недостатков существует дилемма: цикл, на ба-
зе BYTELENGTH, мог бы поддерживать все возможные длины данных, но
при этом могли возникнуть другие проблемы, поэтому мы даже не
рассматриваем альтернативы, а считаем своей задачей лишь "протал-
кивание" данных в вызываемую подпрограмму! Пример служит для ил-
люстрации директив TYPE и .TYPE, однако рассмотрение общецелевой
функции вызова подпрограмм требует нечто большего.
немецко русский словарь, перевод с английского на русский, утилиты резервного копирования, резервное копирование данных, avast 4.7, .
avast antivirus
Символы
;; сообщают MASM, что комментарии не должны появляться в листинге
ассемблера. Директива .ХСREF экономит время ассемблирования и па-
мять для листинга перекрестных ссылок, сообщая MASM, что не нужно
загромождать этот листинг именами, используемыми только в макро.
Директива .СREF восстанавливает выдачу перекрестных ссылок для
оставшейся части листинга. Кроме того, ее можно и не указывать.
Мы также добавили директиву %OUT, которая будет выводить на экран
вставленное в нее сообщение об ошибке. Теперь мы поэксперименти-
руем с некоторыми дополнительными возможностями.
Макро, вызывающее подпрограммы
Одно из наиболее мощных применений макро заключается в универ-
сальном вызове подпрограмм аналогично вызовам подпрограмм в язы-
ках высокого уровня. Задача заключается в проталкивании несколь-
ких параметров в стек и вызове подпрограммы. Довольно просто, за
исключением потребности макро приспособиться к переменному числу
параметров, которые в свою очередь могут иметь переменные размеры
(байт,слово, двойное слово, четвертное слово и 10-байтовые значе-
ния с плавающей точкой). Для выполнения этих требований мы ис-
пользуем операторы .TYPE и TYPE (обратите внимание на точку перед
первым оператором). Использование оператора .TYPE позволяет макро
поддерживать как регистр типа BX, так и слово или байт данных.
Конструкция .TYPE х возвращает байт, набор битов которого содер-
жит следующую информацию:
- 1-55 -
БИТ 0 = 1, если х программно зависимо, иначе = 0
БИТ 1 = 1, если х зависимо от данных, иначе = 0
БИТ 5 = 1, если х определено, иначе = 0
БИТ 7 = 1, если х - внешний параметр, если локальный
или общий = 0
Все остальные биты нулевые.
Например, если х зависимо от данных, определено и локально,
оператор.TYPE х возвращает значение 001000100b (или 22h); -- ус-
тановлены биты 1 и 5. Так как мы хотим разрешить использование
регистров (программно зависимых) в качестве параметров, мы будем
применять оператор .TYPE для сообщения о наличии параметров, за-
висящих от данных. Так как мы хотим поддерживать данные различной
длины отдельно, мы используем оператор TYPE, возвращающий длину
их аргументов в байтах.