NASM | |
---|---|
![]() | |
Тип | компилятор |
Автор | Simon Tatham, Julian Hall |
Разработчики | H. Peter Anvin, Jim Kukunas, Cyrill Gorcunov, Frank B. Kotler |
Написана на | Си[1] |
Операционная система | Linux, Mac OS, Windows, DOS, KolibriOS |
Аппаратная платформа | x86, x86_64 |
Последняя версия | |
Лицензия | LGPL, с версии 2.07 — упрощённая лицензия BSD |
Сайт | nasm.us |
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[3].
NASM успешно конкурирует со стандартным в Linux- и многих других UNIX-системах ассемблером gas.[4][5][6] Считается, что качество документации у NASM выше, чем у gas.[6] Кроме того, ассемблер gas по умолчанию[7] использует AT&T-синтаксис, ориентированный на процессоры не от Intel, в то время как NASM использует вариант традиционного для x86-ассемблеров Intel-синтаксиса; Intel-синтаксис используется всеми ассемблерами для DOS/Windows, например, MASM, TASM, fasm.
В NASM используется Intel-синтаксис записи инструкций. Предложение языка ассемблера NASM (строка программы) может состоять из следующих элементов:
Метка Инструкция Операнды Комментарий
Операнды отделяются между собой запятой. Перед строкой и после инструкции можно использовать любое количество пробельных символов. Комментарий начинается с точки с запятой, а концом комментария считается конец строки. В качестве инструкции может использоваться команда или псевдокоманда (директива компилятора). Если строка очень длинная, то её можно перенести на следующую, используя обратный слеш \
, подобно тому, как это делается в языке Си.
NASM компилирует программы под различные операционные системы в пределах x86-совместимых процессоров. Находясь в одной операционной системе, можно беспрепятственно откомпилировать исполняемый файл для другой.
Компиляция программ в NASM состоит из двух этапов. Первый — ассемблирование, второй — компоновка. На этапе ассемблирования создаётся объектный код. В нём содержится машинный код программы и данные, в соответствии с исходным кодом, но идентификаторы (переменные, символы) пока не привязаны к адресам памяти. На этапе компоновки из одного или нескольких объектных модулей создаётся исполняемый файл (программа). Операция компоновки связывает идентификаторы, определённые в основной программе, с идентификаторами, определёнными в остальных модулях, после чего всем идентификаторам даются окончательные адреса памяти или обеспечивается их динамическое выделение.
Для компоновки объектных файлов в исполняемые в Windows можно использовать свободный бесплатно распространяемый компоновщик alink[5](для 64-битных программ компоновщик GoLink), а в Linux — компоновщик ld, который есть в любой версии этой операционной системы.
Для ассемблирования файла нужно ввести следующую команду:
nasm -f format filename -o output
Компилятор обрабатывает текст программы в несколько проходов, благодаря чему можно инструкции перехода размещать до объявления соответствующих меток.
В командах условного и безусловного (jmp
) переходов используется по умолчанию ближний тип переходов — near
. Поэтому при возможности короткого перехода, чтобы не завысить размер программы на лишний байт, необходимо специально указать тип перехода short
. С версии 0.98.09b были добавлены опции оптимизации -Ox, которые позволяют автоматически оптимизировать размер инструкций перехода[8], в более ранних версиях или без таких опций минимальный размер программы можно получить только ручной модификацией исходного кода.
NASM поддерживает множество форматов выходных файлов, среди них[9]:
Формат выходного файла можно задать с помощью ключа командной строки -f. Форматы могут расширять синтаксис некоторых инструкций и добавлять собственные инструкции.
Примеры программы Hello, world!, которая выводит соответствующее сообщение и завершается.
SECTION .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,'$'
%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
; 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
SECTION .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
global _start
section .text
_start:
mov rax, 1 ; system call 1 is write
mov rdi, 1 ; file handle 1 is stdout
mov rsi, message ; address of string to output
mov rdx, 13 ; number of bytes
syscall ; invoke operating system to do the write
mov eax, 60 ; system call 60 is exit
xor rdi, rdi ; exit code 0
syscall ; invoke operating system to exit
message:
db "Hello, World", 10 ; note the newline at the end
SECTION .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:
.intel_syntax
, появилась в gas-2.10; см. gas/NEWS (англ.). Проверено 18 июля 2010. Архивировано 18 февраля 2012 года.В этой статье не хватает ссылок на источники информации. |
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .