NASM был создан Саймоном Тэтхемом совместно с Юлианом Холлом и в настоящее время развивается небольшой командой разработчиков на SourceForge.net. Первоначально он был выпущен согласно своей собственной лицензии, но позже эта лицензия была заменена на GNU LGPL после множества проблем, вызванных выбором лицензии. Начиная с версии 2.07 лицензия заменена на «упрощённую BSD» (BSD из 2 пунктов).
NASM может работать на платформах, отличных от x86, таких как SPARC и PowerPC, однако код он генерирует только для x86 и x86-64[2].
NASM успешно конкурирует со стандартным в Linux- и многих других UNIX-системах ассемблером gas.[3][4][5] Считается, что качество документации у NASM выше, чем у gas.[5] Кроме того, ассемблер gas по умолчанию[6] использует AT&T-синтаксис, ориентированный на процессоры не от Intel, в то время как NASM использует вариант традиционного для x86-ассемблеров Intel-синтаксиса; Intel-синтаксис используется всеми ассемблерами для DOS/Windows, например, MASM, TASM, fasm.
Синтаксис языка
В NASM используется Intel-синтаксис записи инструкций. Предложение языка ассемблера NASM (строка программы) может состоять из следующих элементов:
МеткаИнструкцияОперандыКомментарий
Операнды разделяются между собой запятой. Перед строкой и после инструкции можно использовать любое количество пробельных символов. Комментарий начинается с точки с запятой, а концом комментария считается конец строки. В качестве инструкции может использоваться команда или псевдокоманда (директива компилятора). Если строка очень длинная, то её можно перенести на следующую, используя обратный слеш \ подобно тому, как это делается в языке Си.
Компиляция и компоновка
NASM компилирует программы под различные операционные системы в пределах x86-совместимых процессоров. Находясь в одной операционной системе, можно беспрепятственно откомпилировать исполняемый файл для другой. В общем встроенные средства NASM позволяет компилировать не только программы, но и файлы с любым содержимым. Также мощный макро-препроцессор значительно расширяет возможности для программирования.
Компиляция программ в NASM состоит из двух этапов. Первый — ассемблирование, второй — компоновка. На этапе ассемблирования создаётся объектный код. В нём содержится машинный код программы и данные, в соответствии с исходным кодом, но идентификаторы (переменные, символы) пока не привязаны к адресам памяти. На этапе компоновки из одного или нескольких объектных модулей создаётся исполняемый файл (программа). Операция компоновки связывает идентификаторы, определённые в основной программе, с идентификаторами, определёнными в остальных модулях, после чего всем идентификаторам даются окончательные адреса памяти или обеспечивается их динамическое выделение.
Для компоновки объектных файлов в исполняемые в Windows можно использовать свободный бесплатно распространяемый компоновщик alink[4](для 64-битных программ компоновщик GoLink), а в Linux — компоновщик ld, который есть в любой версии этой операционной системы.
Для ассемблирования файла нужно ввести следующую команду:
nasm-fformatfilename-ooutput
Инструкции перехода
Компилятор обрабатывает текст программы в несколько проходов, благодаря чему можно инструкции перехода размещать до объявления соответствующих меток.
В командах условного и безусловного (jmp) переходов используется по умолчанию ближний тип переходов — near. Поэтому при возможности короткого перехода, чтобы не завысить размер программы на лишний байт, необходимо специально указать тип перехода short. С версии 0.98.09b были добавлены опции оптимизации -Ox, которые позволяют автоматически оптимизировать размер инструкций перехода[7], в более ранних версиях или без таких опций минимальный размер программы можно получить только ручной модификацией исходного кода.
Формат выходных файлов
NASM поддерживает множество форматов выходных файлов, среди них[8]:
bin — файл произвольного формата, определяемого только исходным кодом. Пригоден как для файлов данных, так и для модулей с исполняемыми кодами — например, системных загрузчиков, образов ПЗУ, модулей операционных систем, драйверов .SYS в MS-DOS или исполняемых файлов .COM.
Формат выходного файла можно задать с помощью ключа командной строки -f. Форматы могут расширять синтаксис некоторых инструкций и добавлять собственные инструкции.
SECTION.datamsgdb"Hello,world!",0xalenequ$-msgSECTION.textglobal_start; the program entry point_start:moveax,4; 'write' syscallmovebx,1; file descr. 1 (stdout)movecx,msg; pointer to the datamovedx,len; amount of dataint0x80; call to the kernelmoveax,1; '_exit' syscallmovebx,0; zero exit code (success)int0x80; call to the kernel
global_startsection.text_start:movrax,1; system call 1 is writemovrdi,1; file handle 1 is stdoutmovrsi,message; address of string to outputmovrdx,13; number of bytessyscall; invoke operating system to do the writemoveax,60; system call 60 is exitxorrdi,rdi; exit code 0syscall; invoke operating system to exitmessage:db"Hello,World",10; note the newline at the end
SECTION.textorg0x100; эта директива нужна только в случае .com файла, в котором нет никаких секцийmovah,0x9movdx,helloint0x21movax,0x4c00; ah == 0x4c al == 0x00int0x21SECTION.datahelloDB"Hello,world!",0xd,0xa,'$'
SECTION.datamsgdb"Hello,world!",0xalenequ$-msgSECTION.textglobal_start; the program entry point_start:pushdwordlenpushdwordmsgpushdword1; 1 is the file descriptor of stdoutmoveax,4; 4 is the 'write' syscallpusheax; we must leave an extra dword on the stackint0x80; call to the kerneladdesp,16; clean up the stackpushdword0; 0 is the exit code (success)moveax,1; 1 is the '_exit' syscallpusheax; extra dword on the stackint0x80; call to the kernel; no cleanup - we will never return
bits32%include'mos.inc'section.textMOS_HEADER01main,image_end,memory_end,stacktop,0,0main:redraw:calldraw_windowwait_event:MOS_WAITEVENTdeceaxjzredrawdeceaxjzkey;button pressed; we have only one button, closeMOS_EXITkey:;key pressed, read it and ignoremoveax,MOS_SC_GETKEYint0x40jmpwait_eventdraw_window:MOS_STARTREDRAWxoreax,eaxmovebx,10*65536+150movecx,40*65536+50movedx,0x33FFFFFFmovedi,headerint0x40;define&draw windowmoveax,MOS_SC_WRITETEXTmovebx,30*65536+10movecx,0x80000000movedx,stringint0x40;display stringMOS_ENDREDRAWretsection.dataheaderdb'HelloWorldtest',0stringdb'Hello,World!',0image_end:section.bssalignb4stackresb1024stacktop:memory_end:
Известные программы, написанные на NASM
Asmutils — набор системных утилит для операционных систем BSD, UnixWare, Solaris и AtheOS.
Проект AsmOS[10] — операционная система на ассемблере NASM (сейчас на стадии разработки).
↑1.1 What Is NASM? (неопр.)The Netwide Assembler: NASM. Официальный сайт. — «NASM, is an 80x86 and x86-64 assembler». Дата обращения: 14 июля 2010. Архивировано из оригинала 18 февраля 2012 года.
↑Поддержка Intel-синтаксиса, вызываемого через специальную директиву .intel_syntax, появилась в gas-2.10; см. gas/NEWS(англ.). Дата обращения: 18 июля 2010. Архивировано из оригинала 18 февраля 2012 года.
↑Chapter 7: Output Formats (неопр.). The Netwide Assembler: NASM. Официальный сайт. Дата обращения: 14 июля 2010. Архивировано из оригинала 18 февраля 2012 года.