Системный вызов write (1)
Часть раздела Основы путешествия по Assembly на Coddy — урок 35 из 45.
Вы уже знаете, как завершить программу. Но бесшумное завершение не очень полезно. Вы хотите, чтобы ваша программа выводила данные, чтобы пользователь мог что-то увидеть.
Для этого вам понадобится системный вызов write.
Что такое системный вызов write?
Системный вызов write сообщает операционной системе о необходимости вывести текст на экран (или записать в файл). Это то, как ваша программа создает вывод.
Номер системного вызова для write — 1.
Как работает write:
В отличие от системного вызова exit (которому требуется только один аргумент), write требует три аргумента:
| Аргумент | Регистр | Что он делает | Пример |
|---|---|---|---|
| Файловый дескриптор | rdi | Куда писать (1 = экран) | mov rdi, 1 |
| Адрес буфера | rsi | Где текст находится в памяти | mov rsi, message |
| Количество байт | rdx | Сколько байт напечатать | mov rdx, 13 |
Системный вызов write в действии:
mov rax, 1 ; номер системного вызова для write
mov rdi, 1 ; файловый дескриптор 1 = stdout (экран)
mov rsi, msg ; адрес строки для вывода
mov rdx, 13 ; количество байт для вывода
syscall ; запрос к ОС на выводЧтобы вывести сообщение на экран, нам понадобится 5 строк. Сначала мы помещаем номер системного вызова 1 в rax для записи. Затем мы помещаем 1 в rdi, чтобы указать ОС вывести данные на экран.
Затем мы помещаем адрес строки (msg) в rsi. После этого мы помещаем количество байт (13) в rdx. Наконец, мы выполняем syscall, чтобы попросить ОС выполнить вывод.
Что происходит при выполнении write:
- Процессор переходит в ядро Linux
- Ядро видит: "write syscall"
- Оно считывает
rdi(куда писать),rsi(где находится текст) иrdx(сколько байт)
- Она выводит текст на экран
- Она возвращает управление вашей программе
Собираем всё вместе со строкой:
section .data
msg db 'Hello', 0x0a ; строка с символом новой строки
section .text
global _start
_start:
mov rax, 1 ; системный вызов write
mov rdi, 1 ; stdout
mov rsi, msg ; адрес строки
mov rdx, 6 ; длина (Hello + новая строка = 6 байт)
syscall
mov rax, 60 ; системный вызов exit
mov rdi, 0
syscallЭта программа выводит Hello и затем завершает работу.
Задание
Напишите программу, которая выводит сообщение "Hi" с последующим символом новой строки. Используйте системный вызов write.
Строка уже определена для вас в тестовой среде. Вам нужно только написать настройку системного вызова.
Попробуйте сами
section .data
msg db 'Hi', 0x0a
msgLen equ $ - msg
section .text
global _start
_start:
; TODO: Настроить и вызвать системный вызов write для вывода msg
; Используйте rax=1, rdi=1, rsi=msg, rdx=msgLen
; Выход из программы
mov rax, 60
mov rdi, 0
syscallВ этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Основы
1Машина
Что такое CPUПамятьРегистры против памятиКак работают инструкцииПаттерн двух файловАрхитектура x86-643Первая инструкция — MOV
Что такое MOV?MOV: непосредственные значенияMOV: из регистра в регистрMOV: из памяти в регистрMOV: из регистра в памятьLEA — загрузка адресаMOV с операндами разных размеровПрактика: обмен значениями регистровИтоги: испытание MOV6Системный вызов write
Системный вызов write (1)Дескриптор файла (rdi)Адрес буфера (rsi)Количество байт (rdx)Собираем всё вместеПечать двух строкВажность новой строкиИтоги: Настройка write