Ассемблер
Как написать в Linux программу на ассемблере x64: Hello World
Чтобы написать Hello World на ассемблере x64 в Linux, используйте NASM-синтаксис, секцию данных для строки, точку входа _start, системный вызов write для вывода текста и системный вызов exit для завершения программы. Затем соберите файл командой nasm -f elf64, свяжите объектный файл через ld и запустите программу как обычный исполняемый файл
Установите инструменты
На Debian или Ubuntu обычно достаточно:
sudo apt install nasm binutils
Проверьте NASM:
nasm -v
Проверьте linker:
ld -v
NASM превращает исходный .asm в объектный файл. ld связывает объектный файл в исполняемую программу
Создайте hello.asm
Создайте файл hello.asm:
section .data
msg db "Hello, world!", 10
len equ $ - msg
section .text
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, len
syscall
mov rax, 60
xor rdi, rdi
syscall
Это минимальная программа под Linux x86-64. Она не использует C-библиотеку и не вызывает printf. Она напрямую обращается к ядру через syscall
Что делает код
В секции .data хранится строка:
msg db "Hello, world!", 10
Число 10 — перевод строки. Константа:
len equ $ - msg
считает длину строки от текущей позиции $ до метки msg
В секции .text находится код. Метка _start — точка входа программы. Когда вы связываете программу напрямую через ld, управление приходит именно сюда
Первый системный вызов:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, len
syscall
В Linux x64 номер системного вызова кладется в rax. Для write это 1. Первый аргумент идет в rdi, второй — в rsi, третий — в rdx. Поэтому:
rdi = 1означает stdout;rsi = msgозначает адрес строки;rdx = lenозначает длину строки.
Второй системный вызов:
mov rax, 60
xor rdi, rdi
syscall
завершает программу. 60 — номер exit, а rdi = 0 — код успешного завершения
Соберите и запустите
В той же папке выполните:
nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello
./hello
Ожидаемый результат:
Hello, world!
Если Linux пишет Permission denied, проверьте права:
chmod +x hello
./hello
Обычно ld сразу создает исполняемый файл с нужными правами, но проверка полезна
Почему этот код не подходит для DOSBox
В DOSBox учебные примеры часто используют TASM, int 21h, сегменты и 16-битные регистры. В Linux x64 используется другой формат файла, другие регистры и другая связь с операционной системой. Команда syscall из примера выше не является DOS-функцией
Если вы видите в коде int 21h, это почти наверняка DOS-пример. Если видите rax, rdi, rsi, syscall, это современный x86-64 код для Linux или похожей среды, но не для TASM в DOSBox
Частые ошибки
Забыли global _start
Без global _start linker может не увидеть точку входа
Собирают не в elf64
Для Linux x64 укажите:
nasm -f elf64
Формат bin или obj для этой задачи не подходит
Путают строку и длину
write не ищет конец строки сам. Ему нужно явно передать длину в rdx
Запускают объектный файл
Файл hello.o не запускают. Запускается файл hello, полученный после ld
Что почитать дальше по ассемблеру
Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:
- Как написать Hello World на ассемблере
- Hello World на ассемблере: зачем он сложнее, чем в C++
- Как запустить программу на ассемблере
- Как запустить программу на ассемблере в DOSBox