|
Ушел с форума
16371 / 7683 / 1080
Регистрация: 11.11.2010
Сообщений: 13,757
|
|
Руководство по препроцессору FASM09.09.2014, 12:53. Показов 21685. Ответов 7
Метки нет (Все метки)
Руководство по препроцессору FASM перевод TAJGA FASM Tutorial by vid - FASM preprocessor guide перевел S.T.A.S. | последняя редакция: 22 июня 2004г. Содержание
4
|
|
| 09.09.2014, 12:53 | |
|
Ответы с готовыми решениями:
7
Вызываю dll (написанную на vc++2008) из Fasm. Через 40 секунд вылет из программы.Без вызова dll из Fasm программа не вылетает. Вопрос по препроцессору C Директива препроцессору #pragma |
|
Ушел с форума
16371 / 7683 / 1080
Регистрация: 11.11.2010
Сообщений: 13,757
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 09.09.2014, 12:54 [ТС] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
1. Об этом документе
Я написал это потому что вижу, как многие задают вопросы на форуме FASM, связанные с непониманием идей или особенностей препроцессора. (Я не отговариваю Вас задавать такие вопросы, непонимание чего-то - это вполне нормально, и если Ваш вопрос не чересчур сложен, кто-нибудь наверняка на него ответит). Если Вам что-нибудь из туториала покажется непонятным, пожалуйста, напишите на форум FASM, форум WASM, автору или переводчику. 2. Общие понятия 2.1. Что такое препроцессор Препроцессор - это программа (или чаще - часть компилятора), которая преобразует исходный текст непосредственно перед компиляцией. К примеру, если Вы используете какой-либо кусок кода довольно часто, можно дать ему некое имя и заставить препроцессор повсеместно заменять это имя в исходном тексте на соответствующий ему код. Другой пример - Вы хотите имитировать инструкцию, которая на самом деле не существует. В таком случае препроцессор может заменять её последовательностью инструкций дающих желаемый эффект. Препроцессор просматривает исходный текст и заменяет некоторые вещи другими. Но как объяснить препроцессору, что именно он должен делать? Для этих целей существуют директивы препроцессора. О них мы и будем говорить. Препроцессор понятия не имеет о инструкциях, директивах компилятора и прочих подобных вещах. Для него существуют собственные команды, и он игнорирует всё остальное. 2.2. Комментарии ";" Подобно большинству ассемблеров, комментарии в FASM начинаются с точки с запятой ";". Всё, что следует за этим символом до конца строки игнорируется и удаляется из исходника. К примеру, исходный текст
ПРИМЕЧАНИЕ: Строка, полностью состоящая из комментария не будет удалена. Она становится пустой строкой (см. пример выше). Это будет важно в дальнейшем. 2.3. Перенос строки (Line Break "\") Если строка выглядит слишком длинной, возможно разделить её на несколько, используя символ "\". При обработке препроцессором следующая строка будет добавлена к текущей. Например:
В строке после символа \ могут быть только пробелы или комментарии. Ранее, я упоминал, что строка, состоящая только из комментария не удаляется, а заменяется на пустую строку. Это значит, что код, подобный этому:
2.4. Директива INCLUDE Синтаксис:
Например:
You may have problem to include ' in string declared using 's or " in string declared using "s. For this reason you must place the character twice into string, in that case it won't end string and begin next as you may think, but it will include character into string literaly. For example:
It's same for ". 3. Присваивания (Equates) 3.1. Директива EQU Простейшая команда препроцессора. Синтаксис:
Например:
Даже это работает:
name2 может быть не только единичным идентификатором, берутся все символы до конца строки. name2 может и отсутствовать, тогда name1 будет заменен на пустое место. Например:
Можно заставить препроцессор прекратить заменять идентификаторы, определённые директивой EQU. Это делает директива RESTORE Синтаксис:
Например:
Например:
Например:
2
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Ушел с форума
16371 / 7683 / 1080
Регистрация: 11.11.2010
Сообщений: 13,757
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 09.09.2014, 12:56 [ТС] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4. Простые макросы без аргументов
4.1. Определение простых макросов Использую EQU можно делать наиболее простые замены в исходном тексте при обработке препроцессором. Большими возможностями обладают макросы. Командой MACRO можно создавать собственные инструкции. Синтаксис:
Например:
4.2. Вложенные макросы Макросы могут быть вложенными один в другой. То есть, если мы переопределим макрос, будет использовано последнее определение. Но если в теле нового определения содержится тот же макрос, то будет использовано предыдущее определение. Посмотрите пример:
Как и в случае с директивой EQU, можно отменить определение макроса. Для этого используется директива PURGE с указанием имени макроса. Синтаксис:
4.4. Поведение макросов Имя макроса будет заменено его телом не только в том случае, если оно расположено в начале строки. Макрос может находиться в любом месте исходного текста, где допустима мнемоника инструкции (например, add или mov). Всё потому, что основное предназначение макросов - имитировать инструкции. Единственное исключение из этого правила - макросы недопустимы после префиксов инструкций (rep). Пример:
. Всё же, переопределение инструкций не всегда хорошая идея - кто-нибудь читая Ваш код может быть введён в заблуждение, если он не знает, что инструкция переопределена.Также, возможно переопределять директивы ассемблера:
5.1. Макросы с одним аргументом Макросы могут иметь аргумент. Аргумент представляет собой какой-либо идентификатор, который будет повсюду заменён в теле макроса тем, что будет указанно при использовании. Синтаксис:
![]() 5.2. Макросы с несколькими аргументами У макросов может быть несколько аргументов, разделённых запятыми ",":
.Если при использовании макроса указать меньше аргументов, чем при определении, то значения неуказанных будет пустым:
Возможно, появится необходимость объявить метку внутри тела макроса:
Синтаксис:
Если Вам нужно несколько локальных меток - не проблема, их можно указать в одной директиве LOCAL, разделив запятыми:
2
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Ушел с форума
16371 / 7683 / 1080
Регистрация: 11.11.2010
Сообщений: 13,757
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 09.09.2014, 12:57 [ТС] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
5.4. Оператор объединения #
У макроязыка FASMа есть ещё одна возможность - манипуляции с идентификаторами. Делается это оператором #, который объединяет два идентификатора в один. К примеру, a#b становится ab, а aaa bbb#ccc ddd -- aaa bbbccc ddd. Оператор # может быть использован только внутри тел макросов, а объединение символов происходит после замены аргументов макроса параметрами. Так что его можно использовать для создания новых идентификаторов из переданных в макрос параметров:
Оператор # способен так же объединять символьные строки:
Существует оператор, преобразующий идентификатор в символьную строку. Он так же может быть использован только внутри макросов:
6.1. Определение макросов с групповым аргументом У макросов могут быть так называемые групповые аргументы. Это позволяет использовать переменное количество аргументов. При определении макроса, групповой аргумент заключается в квадратные скобочки "[" и "]": Синтаксис:
6.2. Директива "COMMON" Для работы с групповыми аргументами применяются специальные директивы препроцессора. Они могут быть использованы только внутри тела макроса имеющего групповой аргумент. Первая такая директива - это "COMMON". Она означает, что после нее имя группового аргумента будет замещаться всеми аргументами сразу:
Аргументы можно обрабатывать и по-отдельности. Для этого служит директива "FORWARD". Часть тела макроса после этой директивы обрабатывается препроцессором для каждого аргумента из группы:
"REVERSE" - это аналог "FORWARD", но обрабатывает группу аргументов в обратном порядке - от последнего к первому:
Три вышеупомянутые директивы могут разделять тело макроса на блоки. Каждый блок обработается препроцессором после предыдущего. Например:
У локальных меток в макросах есть ещё одно полезное свойство. Если директива "LOCAL" находится внутри блока "FORWARD" или "REVERSE", то уникальное имя метки сгенерируется для каждого аргумента из группы, и в последующих блоках "FORWARD" и/или "REVERSE" для каждого аргумента будет использована соответствующая ему метка:
6.7. Макросы с несколькими групповыми аргументами Возможно использовать и несколько групповых аргументов. В этом случае определение макроса не будет выглядеть как:
В действительности, FASM не имеет директив для условного препроцессинга. Но директива ассемблера "if" может быть использована совместно с возможностями препроцессора для получения тех же результатов, что и при условном препроцессинге. (Но в этом случае увеличивается расход памяти и времени). Как известно, оператор "if" обрабатывается во время ассемблирования. Это значит, что условие в этом операторе проверяется после обработки исходного текста препроцессором. Именно это обеспечивает работу некоторых логических операций. Я не буду рассказывать о деталях времени ассемблирования (логических операциях вроде "&", "|" и тому подобном) - читайте об этом в документации FASM. Я лишь расскажу об операторах проверки условия используемых препроцессором.
2
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Ушел с форума
16371 / 7683 / 1080
Регистрация: 11.11.2010
Сообщений: 13,757
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 10.09.2014, 04:59 [ТС] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
7.1. Оператор "EQ"
Простейший логический оператор - это "EQ". Он всего лишь сравнивает два идентификатора - одинаковы ли их значение. Значение abcd eq abcd - истина, а abcd eq 1 - ложь и так далее... Это полезно для сравнения символов, которые будут обработаны препроцессором:
Пример макроса:
7.2. Оператор "EQTYPE" Ещё один оператор - "EQTYPE". Он определяет, одинаков ли тип идентификаторов. Существующие типы:
Когда мы сравниваем что-то посредством "EQTYPE", то это что-то может быть не только единичным идентификатором, но и их комбинацией. В таком случае, результат eqtype истина, если не только типы, но и порядок идентификаторов совпадают. К примеру, if eax 4 eqtype ebx name - верно, так как name - это метка, и её тип - численное выражение. Пример расширенной инструкции mov, которая позволяет перемещать данные между двумя ячейками памяти:
7.3. Оператор "IN" Бывают случаи, когда в условии присутствует слишком много "EQ":
В FASM, структуры практически тоже самое, что и макросы. Определяются они посредством директивы STRUC: Синтаксис:
Существуют хитрый приём, позволяющий не указывать аргументы, если они равны 0:
ПРИМЕЧАНИЕ: часто используется так же макрос или структура struct, которая определяется для расширения возможностей при определении структур. Не путайте struct и struc.
3
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Ушел с форума
16371 / 7683 / 1080
Регистрация: 11.11.2010
Сообщений: 13,757
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 10.09.2014, 04:59 [ТС] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
9. Оператор FIX и макросы внутри макросов
В стародавние времена, в FASMе отсутствовала одна полезная возможность - создавать макросы внутри других макросов. Например, что бы при развёртывании макроса был бы определён новый макрос. Что-то вроде гипотетичного:
9.1. Explaination of fixes Но со временем, была добавлена новая директива. Она работает подобно "EQU", но обрабатывается до любого другого препроцессинга. (За исключением предварительных операций, про которые говорится в разделе "Общие понятия" - они выполняются как бы до самого препроцессинга, но это уже внутренние детали, не слишком интересные). Директива эта называется FIX: Синтаксис :
Preprocessing line 1: a - Preprocessor finds unknown word, skips it. equ - "equ" is second word of line, so it remembers "a" equals rest of line ("b") and deletes line Preprocessing line 2: b - Preprocessor finds unknown word, skips it. equ - "equ" is second word of line, so it remembers "b" equals rest of line ("a") and deletes line Preprocessing line 3: a - Preprocessor replaces "a" with "1" b - Preprocessor replaces "b" with "a" So it becomes:
Fixing line 1: No symbols to be fixed Preprocessing line 1: a - Preprocessor finds unknown word, skips it. fix - "fix" is second word of line, so it remembers "a" is fixed to rest of line ("b") and deletes line Fixing line 2: "a" is fixed to "1", so line becomes "b fix 1" Preprocessing line 2: b - Preprocessor finds unknown word, skips it. fix - "fix" is second word of line, so it remembers "b" is fixed to rest of line ("1") and deletes line Fixing line 3: "a" is fixed to "1", "b" is fixed to "1" so line becomes "1 1" Preprocessing line 3: 1 - Preprocessor finds unknown word, skips it. 1 - Preprocessor finds unknown word, skips it. This was only example to see how fixing works, usually it isn't used in this manner. 9.2. Using fixes for nested macro declaration Now back to declaring macro inside macro - First, we need to know how are macros preprocessed. You can quite easily make it out yourself - on macro declaration macro body is saved, and when macro is being expanded preprocessor replaces line with macro usage by macro body and internally declares equates to handle arguments and continues with preprocessing of macro body. (of course it is more complicated but this is enough for understanding fixes). So where was problem with declaring macro inside macro? First time compiler found "}" inside macro body it took it as end of macro body declaration, so there wasn't any way to include "}" in macro body. So we can easily fix this
Here you see how important is placing of declaration of fixes, because macro body is fixed too before it's loaded by preprocessor. For example this won't work:
NOTE: Character "%" isn't special character for FASM's preprocessor, so you use it just like any normal character, like "a" or "9". It has special meaning AFTER preprocessing, and only when it is only char in whole word ("%" not "anything%anything"). We also need to fix other macro-releated operators:
9.3. Using fixes for moving parts of codes You can also use fixes to move parts of code. In assembly programming is this useful especially when you break code into modules, but you want to have data and code grouped in separate segment/section, but defined in one file. Right now this part of tutorial is TODO, I hope I will write it soon, for now you can look at JohnFound's Fresh's macro library, file
Подобным образом можно пофиксить все остальные проблематичные вещи:
Иногда необходимо фиксить идентификаторы дважды:
Заключение Не забывайте читать документацию FASM. Практически всё, что есть в туториале, можно найти там. Может быть написано и немного сложнее для изучения, но лучше подойдёт в качестве справочной информации. Не так сложно запомнить - 99% пользователей FASM научились его использовать по этой документации и при помощи форума.
3
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Эксперт быдлокодинга
2094 / 528 / 70
Регистрация: 04.11.2010
Сообщений: 1,314
|
|||||||||||
| 18.09.2015, 01:41 | |||||||||||
|
Mikl___, не знаю, в тему ли и быть может об этом тут уже где то писалось, но я не встречал, а поделиться хочется. Если где то уже есть, не сочти за труд удали мою телегу.
По локальным переменным В отличие от простых переменных, адрес локальной переменной просто так в регистры не пишется.
Если по какой либо причине (с оказией) удалось запихнуть один (или все первые четыре) параметры в положенные регистры, то при подстановке этих регистров "масла масляного" не происходит. Т.е. при написании
Кактотаг
1
|
|||||||||||
|
Эксперт быдлокодинга
2094 / 528 / 70
Регистрация: 04.11.2010
Сообщений: 1,314
|
||||||||||||||||||||||||||
| 10.04.2016, 11:01 | ||||||||||||||||||||||||||
|
Очередная мелочёвка из цикла "хозяйке на заметку"
В интернетах читал что помимо инициированных данных
З.Ы. Вполне допускаю что данное наблюдение всем давно известно и прописано во всех мануалах. Однако я человек темный и ленивый, мануалов не читаю, ассемблер учу из под палки. Поэтому вот только дозрел. Короче если инфа не актуальна, то снесите что бы не захламлять ветку.
0
|
||||||||||||||||||||||||||
| 10.04.2016, 11:01 | |
|
Помогаю со студенческими работами здесь
8
Требуется директива препроцессору Требуется директива препроцессору
При создании файла заголовка в Code::Blocks вставляются какие-то команды препроцессору. Руководство Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|
Фото: Daniel Greenwood
kumehtar 13.11.2025
|
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга,
Ты же видел моря и метели.
Как сменялись короны и стяги,
Как эпохи стрелою летели.
- Этот мир — это крылья и горы,
Снег и пламя, любовь и тревоги,
И бескрайние. . .
|