Sadda.ru Ironetcart Андроид Ассемблер MASM32 Linux Все статьи Table of Contents


 

Макросы ассемблера

  Макс Петров май 2013

Макросы

      Ассемблер MASM32 имеет в своем составе средство, позволяющее оптимизировать написание программ с повторяющимися участками кода - макросы ассемблера. Различают макроопределение и макровызов. Макроопределение содержит фрагмент программы, который после замены псевдонимов будет подставлен в ее текст на месте макровызова. Макровызов - имя макроса с перечисленными записями для замены псевдонимов. Макросы могут быть вложенными, то есть в макроопределении допускается использовать макровызовы.

      Макрос может быть определен в любом месте программы - в секции директив (в самом начале), в секции .data или в секции .code, но до первого макровызова. Кроме того, макрос может быть определен в файле (с расширением .inc), в программу такой макрос подключается директивой include. Определение макроса (макроопределение) записывается следующим образом:

имя_макроса MACRO псевдоним_записи_1, псевдоним_записи_2... (текст программы) ENDM

      Макровызов записывается так:

имя_макроса запись_1, запись_2...

      Макровызовы в MASM32 чувствительны к переносу строки, если записей передается много и для улучшения вида и читаемости программы записи удобно расположить в несколько строк, следует использовать символ переноса:

имя_макроса запись_1, запись_2, \ запись_3, запись_4...

      Подчеркну, что в макроопределение из макровызова не передаются переменные или константы, а передаются записи. Записи из макровызова являются текстом для подстановки в макроопределении на место соответствующего по порядку в списке псевдонима. Записями могут быть числа, имена переменных, операторы ассемблера, машинные команды или макровызовы. Например:

.386 .model flat, stdcall option casemap :none include <\masm32\include\windows.inc> include <\masm32\include\kernel32.inc> includelib <\masm32\lib\kernel32.lib> HelloWord MACRO var1, var2, var3 ; макроопределение var3 invoke GetStdHandle, STD_OUTPUT_HANDLE mov hConsoleOutput, eax invoke WriteConsoleA, hConsoleOutput, var1, var2 msg1, ADDR NumberOfChars, 0 ENDM ; конец макроопределения .data hConsoleInput DWORD ? hConsoleOutput DWORD ? NumberOfChars DWORD ? msg1 byte " Hello, World!", 0 .code start: HelloWord addr msg1, sizeof, invoke AllocConsole ; макровызов .while 1 ; бесконечный цикл .endw invoke ExitProcess, 0 ; сообщаем системе, что программа завершена end start

      Программа успешно компилируется.


Макропроцедуры и макрофункции

      Согласно Microsoft MASM Programmer's Guide,

      Макропроцедура раскрывает одно или более законченных определений и может принимать параметры.

      Макрофункция сходна с макропроцедурой и может быть использована подобно ей, но макрофункция возвращает значение... При вызове макрофункции вы должны заключить ее аргументы в круглые скобки, даже если список аргументов пустой. Функция всегда возвращает текст... Определяется макрофункция в точности таким же способом, как и макропроцедура, за исключением того, что макрофункция всегда возвращает значение посредством директивы EXITM.

      Поскольку макрофункция должна возвращать текст, ее результат заключают в угловые скобки. Важной особенностью макрофункций является то, что они могут подставляться в строку (быть одним из аргументом в макровызове или в команде процессору). Например:

. . . . . . . . . . ; макро процедура arraycreation MACRO arrayname, celltype, numberofcells arrayname celltype numberofcells dup (0) ; создаем массив lenthofcell (arrayname) = \ ; вызов макрофункции (SIZEOF arrayname) / numberofcells ; длина ячейки массива ENDM ; макро функция lenthofcell MACRO arrayname EXITM <arrayname&lc> ; создаем имя для макропеременной ENDM .data arraycreation array1, db, 100 ; array1 db 100 dup (0) arraycreation array2, dw, 100 ; array1 dw 100 dup (0) arraycreation array3, dd, 100 ; array1 dd 100 dup (0) ; в результате выполнения вышеприведенного кода, помимо трех ; одномерных массивов, будут динамически созданы три макропеременные, ; хранящие размерность ячейки каждого из массивов: ; array1lc = 1 ; array2lc = 2 ; array3lc = 4 . . . . . . . . . .

      В записи <arrayname&lc> оператор & означает слияние строк. Поскольку arrayname является аргументом макрофункции, препроцессор подставляет на место этого аргумента его значение. Вместе с тем, lc не является аргументом (значения не имеет), это просто строка, поэтому будет присоединена к имени массива в том виде, как она есть.



Добавить комментарий

E-mail:
*


Контрольные цифры:



Ассемблер MASM32

      Простейшая программа на ассемблере (beeper)
      Переменные и типы данных ассемблера
      Регистры процессора IA32
      Консоль ввода-вывода
      API-функция CharToOem и строки ассемблера
      API-функция ReadConsoleInput
      API-функция PeekConsoleInput
      События консоли (таблица)
      Системы счисления, тэги ассемблера, перевод чисел
      Отрицательные числа
      Инкремент и декремент
      Деление (DIV, IDIV)
      VKDEBUG
      Макросы ассемблера
      Воспоминание об Альгамбре на системном динамике
      Командная строка
      Пузырьковая сортировка. Эстафета шариков
      Сортировка расческой
      Быстрая сортировка

     


© Max Petrov При использовании материалов ссылка на sadda.ru обязательна