Меню

Главная
Случайная статья
Настройки
Fasm
Материал из https://ru.wikipedia.org

Fasm (стилизовано fasm под минускул; сокр. от flat assembler) — свободно распространяемый многопроходной ассемблер, написанный Томашем Грыштаром (пол. Tomasz Grysztar). Ассемблер fasm самодостаточен[1], изначально компилировался TASM-ом и стал способен собираться из собственных исходных кодов начиная с 4 мая 1999 в версии 0.90. Также fasm обладает небольшими размерами и очень высокой скоростью компиляции[источник не указан 1336 дней], имеет богатый и ёмкий макро-синтаксис, позволяющий автоматизировать множество рутинных задач[3][4]. Поддерживаются как объектные форматы, так и форматы исполняемых файлов. Это позволяет в большинстве случаев обойтись без компоновщика. В остальных случаях нужно использовать сторонние компоновщики, поскольку таковой вместе с fasm не распространяется.

Помимо базового набора инструкций процессора и сопроцессора

Все вариации fasm непосредственно могут создавать выходные файлы в следующих, предустановленных в ассемблер, форматах: объектные файлы (стандартно для большинства ассемблеров): Executable and Linkable Format (ELF) или Common Object File Format (COFF, классический или в спецификации Microsoft), исполняемые файлы (не требует дополнительных компоновщиков): MZ, ELF или Portable Executable (PE) (WDM драйвера включительно, с возможностью настройки MZ DOS stub). Для генерации файлов в формате, отличном от предустановленных, есть формат бинарный файл, дающий программисту полный контроль за каждым байтом выходного файла, однако всю структуру, содержание и взаимосвязи такого файла программисту придётся описывать непосредственно.

В качестве родной целевой архитектуры используются архитектуры IA32 и x86-64. Присутствует неофициальное дополнение FASMARM, в котором родные целевые архитектуры ARM и ARM64. Реализация целевых архитектур, отличных от родной, аналогична подобной реализации на любом другом ассемблере — для этих целей используются макрокоманды и директивы определения данных.

Содержание

История

Проект был начат в 1999 году Томашом Грыштаром (пол. Tomasz Grysztar), который на тот момент был студентом. Его исходный код был полностью написан на языке ассемблера TASM. Начиная с версии 0.90 (4 мая 1999) ассемблер fasm стал самодостаточен (его исходный код был адаптирован под родной диалект и собирался самим ассемблером fasm). В марте 2000 года fasm был опубликован в сети Интернет.

Изначально fasm запускался только из 16-разрядного плоского реального режима. Затем была добавлена поддержка 32-разрядности и в дополнение к ней поддержка DPMI. Исходный код был переписан таким образом, чтобы его легко можно было портировать под любую x86 операционную систему, поддерживающую 32-битную адресацию. Он был портирован на Windows, затем на Linux.

Принципы
  • fasm стремится использовать минимально возможный набор директив препроцессора, то есть в предустановленном наборе директив не допускается внедрение новых директив, функциональность которых может быть достигнута имеющимся набором директив. Исключение — исторически сложившиеся взаимозаменяемые директивы.
  • fasm — многопроходный ассемблер с оптимистическим предсказанием, то есть на первом же проходе ассемблер делает предположение, что все инструкции принимают свою минимально возможную по размеру форму. Многопроходность также позволяет неограниченно использовать выражения до их объявления.
  • fasm не включает в выходной файл объявления не используемых процедур (реализовано посредством макрокоманд).


Содержимое выходного файла зависит только от содержания исходного кода и не зависит от окружения операционной системы или от параметров переданных в командной строке. Для тех кому данный принцип был неудобен для win32 была разработана обёртка «FA»[5], позволяющая подключить к файлу другой файл не непосредственно в коде, а через командную строку.

Исходный код для fasm может собираться сразу в исполняемый файл, минуя стадии создания промежуточных объектных файлов и их компоновки.

Процесс компиляции

Компиляция программы в fasm состоит из трёх стадий: препроцессирование, синтаксический анализ и ассемблирование.

Препроцессирование

Первая стадия (препроцессинг) выполняется в 1 проход, вначале исходный текст токенизируется, затем в нём распознаются и обрабатываются все директивы процессора, раскрываются все макросы и все символические константы. Поскольку дополнительных проходов этой стадией не предусмотрено, любой элемент языка, обрабатываемый на этой стадии, должен быть вначале объявлен, и только затем он может быть использован.

Синтаксический анализ

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

Ассемблирование

На стадии ассемблирования определяются адреса меток, обрабатываются условные директивы, раскрываются циклы и генерируется собственно программа. Стоит заметить, что fasm — многопроходной ассемблер, что позволяет ему делать некоторые оптимизации (например, генерировать короткий переход на метку вместо длинного). Во время прохода компилятор не всегда может вычислить выражение в условных директивах. В этом случае он делает какой-нибудь выбор и пытается скомпилировать дальше. Благодаря тому, что адреса меток, вычисленные на N-м проходе, используются на N+1-м проходе, этот процесс обычно сходится.

Формат записи инструкций

Используется Intel-синтаксис записи инструкций.

Единственное существенное отличие от формата, принятого в других ассемблерах (MASM, TASM в режиме совместимости с MASM) — значение ячейки памяти всегда записывается как [label_name], а просто label_name означает адрес (то есть порядковый номер) ячейки. Это позволяет обходиться без ключевого слова offset. Также в fasm при переопределении размера операнда вместо byte ptr пишется просто byte, вместо word ptr — word и т. д. Не позволяется использовать несколько квадратных скобок в одном операнде — таким образом, вместо [bx][si] необходимо писать [bx+si]. Эти изменения синтаксиса привели к более унифицированному и лёгкому для чтения коду.

Пример программы

Пример Windows-программы «Hello, world!», которая выводит это сообщение с помощью функции MessageBox и завершается:
         format  pe gui 4.0
         entry   start
         include 'win32a.inc'

 start:
         invoke  MessageBox,NULL,message,message,MB_OK
         invoke  ExitProcess,0

 message db 'Hello, World!',0

         data    import
         library kernel32,'kernel32.dll',\
                 user32,'user32.dll'
         include 'api/kernel32.inc'
         include 'api/user32.inc'
         end     data



Downgrade Counter