Из Руководства программиста MASM 6.1:
A macro - это символическое имя, которое вы даете серии символов (a
текстовый макрос) или одному или нескольким операторам (процедура макроса или
функция).
Когда каждый раз, когда вы используете макрос в коде, как вы пишете prnstr buf2
в какой-то строке, он будет заменен на этапе сборки инструкциями из определения макроса, то есть, как вы бы написали в оригинальном источнике три строки :
mov ah, 09h
lea dx, buf2 ; argument `msg` was replaced by `buf2` value
int 21h
Таким образом, хороший макрос избавит вас от необходимости набирать текст и может несколько помочь с удобочитаемостью исходного кода.
Теперь я обычно не одобряю использование макросов в сборке, особенно новичками, и я попытаюсь объяснить причины этого в следующем тексте, но приведенная выше часть является ответом на ваш вопрос, и если это не так ответьте на свой вопрос, дайте мне знать в комментариях.
Макросы несколько запутывают машинный код, который будет сгенерирован, когда вы выполняете проверку кода какого-либо источника, и вы видите prnstr buf2
, вы должны открыть также определение макроса, чтобы просмотреть, имеет ли смысл сгенерированный код в целом, т. е. если код не ожидал сохранения, например, значения в dx
, а затем более поздний программист добавил prnstr
, забыв, что он изменяет значение dx
. Так что обзор становится более громоздким.
Эта тема продолжается и в отладчике, в отладчике вы видите разобранный фактический машинный код, поэтому вы увидите все эти настоящие инструкции вместо оригинального макроса, использованного в исходном коде. Что может затруднить быстрое понимание того, где вы находитесь (в исходном коде), какую часть вы отлаживаете и откуда пришли инструкции. Кроме того, если конкретная макро-инструкция не подходит и вам нужно «исправить» код, это может быть немного сложнее, чем изменение фактической инструкции в коде (поскольку любое изменение в макросе будет распространяться и на все другие места, где используется).
Кроме того, макрос сохраняет только строки исходного кода, но не конечный машинный код, поэтому, чрезмерно используя их без полного понимания эффекта, вы можете получить намного больший двоичный код, чем вы ожидали.
Наконец, макросы являются особенностью конкретного ассемблера (если поставщик ассемблера намеренно не пытается быть совместимым с другим вендором, например, TASM способен компилировать почти все источники MASM и использует его в промо-текстах как «точку продажи»), в то время как инструкции определяются центральным процессором, поэтому в случае, если на вашей целевой платформе (CPU + OS) имеется много конкурирующих ассемблеров, источники без макросов могут быть более совместимыми между различными ассемблерами (хотя часто есть и небольшие кусочки несовместимости синтаксиса, делающие «портирование» "задача, требующая ручного редактирования исходного кода любым способом).
Конкретный prnstr
кажется мне разумным, хотя, если бы я приводил какой-то пример для начинающих, я бы все-таки писал эти инструкции каждый раз в коде - он используется 5 раз, 5 + 5 строк против 5x3 = 15 строк = источник всего на 5 строк короче, IMO не стоит, так как «написание кода» обычно составляет всего около 10-20% времени разработки и экономии на записи, что также не спасает чтение / просмотр кода и исправление ошибок + обслуживание (эти две часто в разы больше времени разработки, чем написание), в конце концов, ухудшает ситуацию.
Распространенный шаблон использования макросов (неправильных) для начинающих - принимать их за процедуры. Для процедур процессор x86 имеет встроенную поддержку в виде инструкций, таких как call
и ret
, поэтому в случае более длинных фрагментов кода вы можете использовать их вместо макросов, что делает чтение кода немного легче, как в каждом x86 asm-кодер должен знать их, и они видны при разборке в отладчике так же, как был написан источник.
Теперь макросы - это, конечно, большая часть того, что делает MASM отличным инструментом для программистов, поэтому они, безусловно, также имеют свои преимущества:
производительность по сравнению с вызовом процедуры ... пара инструкций call+ret
требует крошечного времени для выполнения, в то время как макрос вводит инструкции непосредственно в исходный поток. Если мы говорим о каком-то интенсивном коде внутреннего цикла, выполняемом миллионы раз в секунду, то макрос вместо call
может иметь какое-то измеримое значение, иногда делая результат лучше (или хуже). Но в других случаях это беспокойство бессмысленно в современных x86, поскольку они будут выполнять call/ret
в течение минимального времени, а более короткий двоичный файл может принести преимущества не столько засорения кэша команд, сколько раздутого расширенного кода.
хороший способ создания разных вариантов кода для разных типов сборок. Вы можете скрыть в макросе, например, другую логику кода LOG(..)
, будучи пустым в производственном процессе, но создавая журнал отладки в сборках отладки или помещая третий аргумент для вызовов процедур в rcx
или rdx
, в зависимости от целевой архитектуры и т. Д. ...
использование новых командных кодов команд (пока не поддерживается ассемблером) удобным способом
И, возможно, многие другие, макросы являются мощным инструментом, вроде низкоуровневой сборки на языке программирования среднего уровня.
Опять же, если вам нужен язык ассемблера сегодня, он чаще всего нужен для настройки производительности. Это означает переписать крошечный кусочек другого кода, написанного на языке программирования высокого уровня, обрабатывающего большой объем данных (узкое место, обнаруженное при профилировании исходного кода), и в этот момент вам обычно не нужны какие-либо функции «среднего уровня», поскольку вам нужно просто точно создать «горячую» часть кода внутреннего цикла, возможно, размером в несколько десятков / сотен строк сборки, и соединить ее с исходным кодом, и вы, вероятно, не найдете интенсивного использования макросов в такой случай.
Я также могу представить множество случаев, когда макросы могли бы помочь (если вы, например, пишете несколько микропроцессоров, и каждый цикл тестирования имеет определенные идентичные части, но вы не хотите, чтобы они были частью «процедуры», тогда макросы идеально подходят) и т.д ...
Но если вы только изучаете основы сборки, вам вообще не нужны макросы, а просто потратьте время на изучение теории компьютерных архитектур и изучение самой сборки.