Разбор Hello nasm
В посте “Hello nasm assembler” я привел пример программы на ассемблере nasm для Mac OS, но совершенно не рассказал как она работает. Повторю её ещё раз код программы:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
; /usr/local/bin/nasm -f macho64 64.asm && ld -macosx_version_min 10.7.0 -lSystem -o 64 64.o && ./64
global start
section .text
start:
mov rax, 0x2000004 ; write
mov rdi, 1 ; stdout
mov rsi, msg
mov rdx, msg.len
syscall
mov rax, 0x2000001 ; exit
mov rdi, 0
syscall
section .data
msg: db "Hello, world!", 10
.len: equ $ - msg
Комментарии к коду программы:
- В языке nasm
;обозначает комментарии. Строчка 1. - В строчке 3
global startдля линкера указывается с какого места начинать выполнение программы - Директива
sectionзадает секции для объектных файлов- .text (строка 5) - для кода, стандартный в Linux
start:в 7 строчке метка, она отмечает место в коде на которое можно переходитьmovиsyscallx86 операторыmovпомещает данные в регистрыsyscallосуществляет системный вызов и передает управление ядру операционной системы
rax, rdi, rsi, rdxрегистры общего назначения в которые кладутся данные, имеют стандартные способы использованияrax- аккумуляторrdi- указатель на получатель для строкrsi- указатель на источник для строкrdx- указатель Ввода/Вывода
0x2000004, 0x2000001константы для идентификации системных вызовов на Windows и Linux будут другие
- .data (строка 19) - для констант, тоже стандартный
- с помощью меток строки 21, 22 можно объявлять переменные, причем
.значит что переменная локальная и относится к ближайшей сверху метке. Точке может быть несколько. db "Hello, world!", 10инициализирует данные в выходном файле, объектном section 3.2.1equ $ - msgприсваивает метке константное значение. В данном случае из отступа начала данной метки вычитается отступ msg и мы получаем длину msg в байтах section 3.2.4
- с помощью меток строки 21, 22 можно объявлять переменные, причем
- .text (строка 5) - для кода, стандартный в Linux