Системный вызов 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Потренируйтесь самостоятельно: Песочница Assembly