Ассемблеры могут быть классифицированы на однопроходные и двухпроходные, каждый из которых имеет свои особенности, преимущества и недостатки. Эта классификация зависит от количества проходов, которые ассемблер делает по исходному коду программы для генерации объектного кода.
Двухпроходные ассемблеры
Большинство ассемблеров являются двухпроходными. Это означает, что они проходят через исходный текст программы дважды:
- Первый проход: Ассемблер создаёт таблицу символов, в которую собирает все определения имен, используемых в программе. Это позволяет ему точно узнать адреса всех меток и переменных перед фактическим преобразованием инструкций и данных в машинный код.
- Второй проход: На этом этапе ассемблер транслирует инструкции в машинный код, используя информацию, собранную в таблице символов во время первого прохода. Это позволяет правильно устанавливать адреса переходов и другие ссылки в коде.
Двухпроходные ассемблеры эффективно справляются с любыми ссылками вперёд, поскольку они уже знают все необходимые адреса к началу второго прохода.
Однопроходные ассемблеры
Однопроходные ассемблеры проходят по исходному коду только один раз, что делает их быстрее двухпроходных ассемблеров:
- Они непосредственно транслируют каждую инструкцию в машинный код, как только она встречается в тексте программы, не дожидаясь полного сбора данных о всех символах.
- Основной проблемой однопроходных ассемблеров является обработка ссылок вперёд, когда нужно указать адрес элемента, который ещё не определён в момент первого (и единственного) чтения. Часто такие случаи требуют дополнительной обработки на стороне загрузчика или использования более сложных механизмов управления памятью.
Вход и выход данных ассемблера
Ассемблеры могут принимать исходный код из различных источников и выдавать разные типы документации:
- Листинг программы с объектным кодом.
- Список ошибок компиляции.
- Таблицу символов с их значениями.
- Таблицу перекрестных ссылок.
- Списки внешних ссылок и подпрограмм.
Некоторые ассемблеры также могут непосредственно загружать и выполнять программу после ассемблирования, в зависимости от предоставленных возможностей и настроек системы.
Выбор между одно- и двухпроходным ассемблером зависит от специфических требований проекта, включая необходимость быстродействия ассемблирования против точности и надёжности генерации кода. Двухпроходные ассемблеры обеспечивают большую гибкость и точность, особенно при работе с большими и сложными программами, тогда как однопроходные могут быть предпочтительны в ситуациях, где время компиляции критично.