Ассемблер

Как написать в 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

Что почитать дальше по ассемблеру

Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x