- NASM
-
NASM Тип Операционная система Последняя версия Лицензия LGPL, с версии 2.07 — упрощённая лицензия BSD
Сайт NASM (Netwide Assembler) — свободный (LGPL и лицензия BSD) ассемблер для архитектуры Intel x86. Используется для написания 16-, 32- и 64-битных программ.
Содержание
История
NASM был создан Саймоном Тэтхемом совместно с Юлианом Холлом и в настоящее время развивается небольшой командой разработчиков на SourceForge.net. Первоначально он был выпущен согласно его собственной лицензии, но позже эта лицензия была заменена на GNU LGPL после множества проблем, вызванных выбором лицензии. Начиная с версии 2.07 лицензия заменена на «упрощённую BSD» (BSD из 2 пунктов).
NASM может работать на платформах, отличных от x86, таких как SPARC и PowerPC, однако код он генерирует только для x86 и x86-64[1].
NASM успешно конкурирует со стандартным в Linux- и многих других UNIX-системах ассемблером gas.[2][3][4] Считается, что качество документации у NASM выше, чем у gas.[4] Кроме того, ассемблер gas по умолчанию[5] использует AT&T-синтаксис, ориентированный на процессоры не от Intel, в то время как NASM использует вариант традиционного для x86-ассемблеров Intel-синтаксиса; Intel-синтаксис используется всеми ассемблерами для под DOS/Windows, например, MASM, TASM, fasm.
Синтаксис языка
В NASM используется Intel-синтаксис записи инструкций. Предложение языка ассемблера NASM (строка программы) может состоять из следующих элементов:
Метка Инструкция Операнды Комментарий
Операнды отделяются между собой запятой. Перед строкой и после инструкции можно использовать любое количество пробельных символов. Комментарий начинается с точки с запятой, а концом комментария считается конец строки. В качестве инструкции может использоваться команда или псевдокоманда (директива компилятора). Если строка очень длинная, то её можно перенести на следующую, используя обратный слеш
\
, подобно тому, как это делается в языке Си.Компиляция и компоновка
NASM компилирует программы под различные операционные системы в пределах x86-совместимых процессоров. Находясь в одной операционной системе, можно беспрепятственно откомпилировать исполняемый файл для другой.
Компиляция программ в NASM состоит из двух этапов. Первый — ассемблирование, второй — компоновка. На этапе ассемблирования создаётся объектный код. В нём содержится машинный код программы и данные, в соответствии с исходным кодом, но идентификаторы (переменные, символы) пока не привязаны к адресам памяти. На этапе компоновки из одного или нескольких объектных модулей создаётся исполняемый файл (программа). Операция компоновки связывает идентификаторы, определённые в основной программе, с идентификаторами, определёнными в остальных модулях, после чего всем идентификаторам даются окончательные адреса памяти или обеспечивается их динамическое выделение.
Для компоновки объектных файлов в исполняемые в Windows можно использовать свободный бесплатно распространяемый компоновщик alink[3](для 64-х битных программ компоновщик GoLink), а в Linux — компоновщик ld, который есть в любой версии этой операционной системы.
Для ассемблирования файла нужно ввести следующую команду:
nasm -f format filename -o output
Инструкции перехода
Компилятор обрабатывает текст программы в несколько проходов, благодаря чему можно инструкции перехода размещать до объявления соответствующих меток.
В командах условного и безусловного (
jmp
) переходов используется по умолчанию ближний тип переходов —near
. Поэтому при возможности короткого перехода, чтобы не завысить размер программы на лишний байт, необходимо специально указать тип переходаshort
. С версии 0.98.09b были добавлены опции оптимизации -Ox, которые позволяют автоматически оптимизировать размер инструкций перехода[6], в более ранних версиях или без таких опций минимальный размер программы можно получить только ручной модификацией исходного кода.Формат выходных файлов
NASM поддерживает множество форматов выходных файлов, среди них[7]:
- bin — файл произвольного формата, определяемого только исходным кодом. Пригоден как для файлов данных, так и для модулей с исполняемыми кодами — например, системных загрузчиков, образов ПЗУ, модулей операционных систем, драйверов .SYS в MS-DOS или исполняемых файлов .COM.
- obj — объектный модуль в формате OMF, совместимый с MASM и TASM.
- win32 и win64 — объектный модуль для 32- и 64-битного кода, совместимый с Win32- и Win64-компиляторами Microsoft.
- aout — объектный модуль в варианте формата a.out, использовавшемся в ранних Linux-системах.
- aoutb — версия формата a.out для BSD-совместимых операционных систем.
- coff — объектный модуль в формате COFF, совместимом с компоновщиком из DJGPP.
- elf32 и elf64 — объектный модуль в форматах ELF32 и ELF64, используемых в Linux и Unix System V, включая Solaris x86, UnixWare и SCO Unix.
Формат выходного файла можно задать с помощью ключа командной строки -f. Форматы могут расширять синтаксис некоторых инструкций и добавлять собственные инструкции.
Примеры программы Hello, world! под разные ОС
Примеры программы Hello, world!, которая выводит соответствующее сообщение и завершается.
Под операционную систему DOSSECTION .text org 0x100 ; эта директива нужна только в случае .com файла, в котором нет никаких секций mov ah, 0x9 mov dx, hello int 0x21 mov ax, 0x4c00 ; ah == 0x4c al == 0x00 int 0x21 SECTION .data hello DB "Hello, world!",0xd,0xa,'$'
Под операционную систему Windows (obj)%include 'WIN32N.INC' EXTERN MessageBoxA Import MessageBoxA user32.dll EXTERN ExitProcess Import ExitProcess kernel32.dll SECTION CODE USE32 CLASS=CODE ..start: push UINT MB_OK push LPCTSTR title push LPCTSTR banner push HWND NULL call [MessageBoxA] push UINT NULL call [ExitProcess] SECTION DATA USE32 CLASS=DATA banner db 'Hello, world!',0xD,0xA,0 title db 'Hello',0
Под операционную систему Windows x64 (obj); Hello.asm EXTERN MessageBoxW EXTERN ExitProcess SECTION .text USE64 start: sub rsp, 28h ; Microsoft x64 calling convention "shadow space" xor rcx, rcx ; HWND hWnd = NULL lea rdx, [banner] ; LPCTSTR lpText = banner lea r8, [title] ; LPCTSTR lpCaption = title xor r9, r9 ; UINT uType = MB_OK call MessageBoxW ; MessageBox(hWnd, lpText, lpCaption, uType) xor rcx, rcx ; UINT uExitCode = 0 call ExitProcess ; ExitProcess(uExitCode) SECTION .data banner dw __utf16__('Hello, world!'),0 title dw __utf16__('Hello!'),0
>nasm -f win64 Hello.asm
>golink Hello.obj kernel32.dll user32.dllПод операционную систему LinuxSECTION .data msg db "Hello, world!",0xa len equ $ - msg SECTION .text global _start ; the program entry point _start: mov eax, 4 ; 'write' syscall mov ebx, 1 ; file descr. 1 (stdout) mov ecx, msg ; pointer to the data mov edx, len ; amount of data int 0x80 ; call to the kernel mov eax, 1 ; '_exit' syscall mov ebx, 0 ; zero exit code (success) int 0x80 ; call to the kernel
Под операционную систему FreeBSDSECTION .data msg db "Hello, world!",0xa len equ $ - msg SECTION .text global _start ; the program entry point _start: push dword len push dword msg push dword 1 ; 1 is the file descriptor of stdout mov eax, 4 ; 4 is the 'write' syscall push eax ; we must leave an extra dword on the stack int 0x80 ; call to the kernel add esp, 16 ; clean up the stack push dword 0 ; 0 is the exit code (success) mov eax, 1 ; 1 is the '_exit' syscall push eax ; extra dword on the stack int 0x80 ; call to the kernel ; no cleanup - we will never return
bits 32 %include 'mos.inc' section .text MOS_HEADER01 main,image_end,memory_end,stacktop,0,0 main: redraw: call draw_window wait_event: MOS_WAITEVENT dec eax jz redraw dec eax jz key ;button pressed; we have only one button, close MOS_EXIT key: ;key pressed, read it and ignore mov eax, MOS_SC_GETKEY int 0x40 jmp wait_event draw_window: MOS_STARTREDRAW xor eax, eax mov ebx, 10*65536 + 150 mov ecx, 40*65536 + 50 mov edx, 0x33FFFFFF mov edi, header int 0x40 ;define&draw window mov eax, MOS_SC_WRITETEXT mov ebx, 30*65536 + 10 mov ecx, 0x80000000 mov edx, string int 0x40 ;display string MOS_ENDREDRAW ret section .data header db 'HelloWorld test',0 string db 'Hello, World!',0 image_end: section .bss alignb 4 stack resb 1024 stacktop: memory_end:
Известные программы, написанные на NASM
- Asmutils — набор системных утилит для операционных систем BSD, UnixWare, Solaris и AtheOS.
- Проект AsmOS[9] — операционная система на ассемблере NASM (сейчас на стадии разработки).
Примечания
- ↑ 1.1 What Is NASM?. The Netwide Assembler: NASM. Официальный сайт. — «NASM, is an 80x86 and x86-64 assembler» Архивировано из первоисточника 18 февраля 2012. Проверено 14 июля 2010.
- ↑ Ассемблеры для Linux: Сравнение GAS и NASM
- ↑ 1 2 Использование ассемблера NASM в Windows
- ↑ 1 2 Рэндолл Хайд. Which Assembler is the Best? (англ.). Архивировано из первоисточника 18 февраля 2012. Проверено 18 июля 2010.
- ↑ Поддержка Intel-синтаксиса, вызываемого через специальную директиву
.intel_syntax
, появилась в gas-2.10; см. gas/NEWS (англ.). Архивировано из первоисточника 18 февраля 2012. Проверено 18 июля 2010. - ↑ C.2.33 Version 0.98.09b with John Coffman patches released 28-Oct-2001. The Netwide Assembler: NASM. Appendix C: NASM Version History. Официальный сайт. Архивировано из первоисточника 18 февраля 2012. Проверено 18 июля 2010.
- ↑ Chapter 7: Output Formats. The Netwide Assembler: NASM. Официальный сайт. Архивировано из первоисточника 18 февраля 2012. Проверено 14 июля 2010.
- ↑ Использование различных компиляторов в КолибриОС
- ↑ Операционная система на ассемблере NASM
Литература
- Рудольф Марек. Ассемблер на примерах. Базовый курс. — СПб.: Наука и техника, 2005. — 240 с. — ISBN 5-94387-232-9
- А. В. Столяров. Программирование на языке ассемблера NASM для ОС Unix. — М.: МАКС Пресс, 2011. — 188 с. — ISBN 978-5-317-03627-0
Ссылки
- Официальный сайт
- Проект NASM на сайте SourceForge.net
- Расширенный ассемблер: NASM
- Введение в NASM (низкоуровневое программирование для Windows)
Для улучшения этой статьи желательно?: - Найти и оформить в виде сносок ссылки на авторитетные источники, подтверждающие написанное.
- Проставив сноски, внести более точные указания на источники.
- Добавить иллюстрации.
Язык ассемблера IDE Трансляторы Форматы синтаксиса Категории:- Программное обеспечение по алфавиту
- Компиляторы
- Ассемблер
Wikimedia Foundation. 2010.