NASM
NASM (Netwide Assembler) — это свободный ассемблер для архитектуры x86-64, предназначенный для преобразования текстовых программ на языке ассемблера в машинный код. Относится к классу ассемблеров с синтаксисом Intel, поддерживает как 16-битные, так и 32-битные и 64-битные режимы работы процессора. NASM распространяется под лицензией BSD (с оговоркой о рекламе), что делает его доступным для коммерческого и некоммерческого использования.
История
NASM был создан в 1996 году программистом Саймоном Тэтхемом (Simon Tatham) в качестве альтернативы существовавшим на тот момент ассемблерам, в первую очередь — MASM (Microsoft Macro Assembler) и TASM (Borland Turbo Assembler). Основной целью разработки было создание ассемблера с открытым исходным кодом, который бы не зависел от платформы Microsoft и поддерживал бы современные на тот момент возможности процессоров Intel.
Первая стабильная версия, NASM 0.98, была выпущена в 1999 году. В 2000-х годах проект активно развивался, появилась поддержка 64-битных расширений (AMD64/Intel 64), а также формата объектных файлов ELF64. В 2007 году вышла версия 2.00, которая включала значительные улучшения в синтаксисе макросов и поддержку новых инструкций (SSE, AVX). С 2010 года разработкой руководит группа энтузиастов под руководством H. Peter Anvin.
На 2025 год последней стабильной версией является NASM 2.16.03 (выпущена в 2023 году). Проект продолжает поддерживаться, хотя основная конкуренция ему исходит от ассемблера FASM (Flat Assembler) и встроенного ассемблера в компиляторах GCC (GNU Assembler, GAS).
Синтаксис и особенности
NASM использует синтаксис Intel, который отличается от синтаксиса AT&T, применяемого в GAS. Основные черты синтаксиса NASM:
- Порядок операндов: команда записывается как
инструкция операнд_назначения, операнд_источника. Например,mov eax, ebx(скопировать значение из регистра ebx в регистр eax). В синтаксисе AT&T порядок обратный:mov %ebx, %eax. - Регистры: обозначаются без префиксов (например,
eax,rax,xmm0). В GAS регистры предваряются знаком процента (%eax). - Непосредственные значения: записываются как числа без префиксов, но для указания размера используются суффиксы (например,
byte,word,dword,qword). Для шестнадцатеричных чисел используется префикс0x(например,0x1A). - Директивы: начинаются с точки (например,
section .text,global _start). NASM не требует обязательного указания размера операнда в большинстве случаев, но для неоднозначных ситуаций (например, при работе с памятью) необходимо явно указывать размер черезbyte,word,dword,qword.
Отличия от других ассемблеров
- От MASM: NASM не поддерживает устаревшие конструкции MASM, такие как
ASSUMEилиSEGMENT, и не требует объявления сегментов в стиле MS-DOS. NASM использует более простую модель плоской памяти (flat memory model). - От TASM: NASM не имеет встроенной поддержки объектно-ориентированных расширений, характерных для TASM (например,
TYPEDEF). - От FASM: NASM менее гибок в плане макросов (FASM позволяет использовать более сложные макросы на этапе сборки), но NASM имеет более широкую поддержку форматов объектных файлов.
Поддерживаемые платформы и форматы
NASM работает на большинстве операционных систем, включая Linux, Windows, macOS, FreeBSD, а также на многих Unix-подобных системах. Он может генерировать объектные файлы в следующих форматах:
- ELF (Executable and Linkable Format) — для Linux, FreeBSD, Solaris.
- COFF (Common Object File Format) — для Windows (32-битные объектные файлы).
- PE (Portable Executable) — для Windows (32-битные и 64-битные исполняемые файлы, DLL).
- Mach-O — для macOS.
- bin — сырой двоичный файл без заголовков (используется для загрузчиков, прошивок, операционных систем).
- aout — устаревший формат для Linux.
- obj — формат MS-DOS/Windows (16-битный).
Также NASM поддерживает генерацию листингов (файлы с расширением .lst), которые показывают соответствие между исходным кодом и сгенерированным машинным кодом.
Применение
NASM широко используется в следующих областях:
- Разработка операционных систем: благодаря поддержке формата
bin, NASM позволяет создавать загрузочные сектора (bootloader) и ядра операционных систем. Например, ядро Linux (до версии 2.6) частично использовало NASM для сборки загрузчика. - Написание драйверов: в Windows и Linux драйверы нижнего уровня часто пишутся на ассемблере для оптимизации критических участков кода.
- Обучение программированию: NASM часто используется в учебных курсах по архитектуре компьютера и низкоуровневому программированию благодаря своей простоте и отсутствию избыточных конструкций.
- Обратная разработка (реверс-инжиниринг): при анализе бинарных файлов NASM позволяет дизассемблировать код (с помощью утилиты
ndisasm) и затем пересобирать его с модификациями. - Встраиваемые системы: для микроконтроллеров и процессоров без операционной системы (например, на базе Intel 8086 или x86-64).
Инструменты в составе NASM
В состав дистрибутива NASM входят несколько утилит:
- nasm — основной ассемблер, преобразующий исходный код (
.asm) в объектный файл. - ndisasm — дизассемблер, преобразующий машинный код обратно в ассемблерный текст (с синтаксисом NASM). Поддерживает дизассемблирование как сырых бинарных файлов, так и объектных файлов (с опцией
-o). - rdf — утилиты для работы с форматом RDOFF (Relocatable Dynamic Object File Format), который используется в некоторых проектах (например, в операционной системе FreeDOS).
Пример программы
Ниже приведён пример простой программы на NASM для Linux (64-битная архитектура), которая выводит строку «Hello, world!» на экран:
```assembly section .data msg db 'Hello, world!', 0xA ; строка с переводом строки len equ $ - msg ; длина строки
section .text global _start
_start: ; системный вызов write (номер 1) mov rax, 1 ; номер системного вызова mov rdi, 1 ; файловый дескриптор (stdout) mov rsi, msg ; адрес строки mov rdx, len ; длина строки syscall
; системный вызов exit (номер 60) mov rax, 60 ; номер системного вызова xor rdi, rdi ; код возврата (0) syscall ```
Для сборки этой программы необходимо выполнить команды: ``bash nasm -f elf64 hello.asm -o hello.o ld hello.o -o hello ./hello ``
Критика и ограничения
Несмотря на популярность, NASM имеет ряд недостатков:
- Сложность макросов: макросы в NASM менее мощные, чем в FASM или GAS (с использованием препроцессора C). Например, нет встроенной поддержки условных макросов на этапе сборки (хотя можно использовать препроцессор
%if). - Отсутствие встроенного линкера: NASM генерирует только объектные файлы; для создания исполняемого файла требуется внешний линкер (например,
ldилиlink.exe). - Ограниченная поддержка отладки: в отличие от GAS, NASM не генерирует отладочную информацию в формате DWARF (хотя может выводить её в формате STABS, но это менее распространено).
- Совместимость с Windows: на Windows NASM требует установки дополнительных утилит (например, MinGW или MSVC) для линковки, что усложняет процесс разработки.
Сравнение с аналогами
| Ассемблер | Синтаксис | Лицензия | Поддержка 64-бит | Форматы объектных файлов | Популярность |
|---|---|---|---|---|---|
| NASM | Intel | BSD | Да | ELF, PE, COFF, Mach-O, bin | Высокая (Linux, Windows) |
| FASM | Intel | BSD | Да | ELF, PE, COFF, bin | Средняя (энтузиасты) |
| MASM | Intel | Проприетарная | Да | COFF, PE, OBJ | Высокая (Windows) |
| TASM | Intel | Проприетарная (заброшен) | Нет | OBJ, COFF | Низкая (устаревший) |
| GAS | AT&T (по умолчанию) | GPL | Да | ELF, PE, Mach-O, COFF | Очень высокая (в составе GCC) |
Интересные факты
- NASM изначально был написан на языке C, но в 2000-х годах часть кода была переписана на C++ для улучшения производительности.
- Название «Netwide» отражает изначальную цель проекта — создание ассемблера, работающего на всех платформах, а не только на DOS/Windows.
- В 2004 году NASM был использован для создания первого загрузчика для операционной системы ReactOS, совместимой с Windows.
- Существует форк NASM — Yasm (Yet Another Assembler), который поддерживает дополнительные архитектуры (например, ARM) и улучшенную поддержку макросов. Yasm был популярен в 2000-х годах, но к 2025 году его развитие практически остановилось.
Источники
- Официальная документация NASM (NASM Manual, версия 2.16.03).
- Tatham, S. (1996). «NASM: The Netwide Assembler» (первоначальная публикация).
- Anvin, H. P. (2007). «NASM 2.00 Release Notes».
- Статья «Comparison of assemblers» в англоязычной Википедии (по состоянию на 2024 год).
- Книга: «Assembly Language for x86 Processors» (Kip R. Irvine, 7-е издание, 2014).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →