Открыть сервис

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-битФорматы объектных файловПопулярность
NASMIntelBSDДаELF, PE, COFF, Mach-O, binВысокая (Linux, Windows)
FASMIntelBSDДаELF, PE, COFF, binСредняя (энтузиасты)
MASMIntelПроприетарнаяДаCOFF, PE, OBJВысокая (Windows)
TASMIntelПроприетарная (заброшен)НетOBJ, COFFНизкая (устаревший)
GASAT&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 →