Системный вызов Exit (60)
Часть раздела Основы путешествия по Assembly на Coddy. Урок 32 из 45.
Самый важный системный вызов для любой программы — exit. Без него ваша программа продолжала бы работать бесконечно или аварийно завершилась бы, достигнув конца памяти.
Номер системного вызова exit — 60.
Синтаксис:
mov rax, 60 ; номер системного вызова для завершения программы
mov rdi, 0 ; код завершения (0 = успешное выполнение)
syscall ; запросить у ОС завершение программыЧто происходит при выполнении syscall с rax = 60:
- CPU переходит в ядро Linux
- Ядро видит: "системный вызов exit с кодом 0"
- Ядро завершает вашу программу
- Ядро возвращает управление оболочке или операционной системе
Код завершения 0 означает успех: программа завершилась без ошибок. Коды завершения от 1 до 255 указывают на различные ошибки. Ты можешь выбрать любое число, чтобы сообщить, что пошло не так.
Почему важны коды завершения:
После завершения программы оболочка (терминал) сохраняет код завершения. Проверить его можно с помощью:
./myprogram
echo $? ; Prints the exit codeЭто полезно для:
- Скриптов, которые проверяют, успешно ли выполнилась программа
- Отладки (разные коды для разных ошибок)
- Объединения программ в цепочку
Полная минимальная программа:
section .text
global _start
_start:
mov rax, 60 ; системный вызов завершения программы
mov rdi, 0 ; код завершения 0 (успешно)
syscallЭта программа не делает ничего видимого. Она просто успешно завершает работу. Но это корректная, полноценная программа.
Давайте расскажем, что такое global _start и _start:.
| Код | Что это | Зачем он нужен |
|---|---|---|
global _start | Указывает компоновщику, где начинается ваша программа | Без этого компоновщик не знает, какая метка является точкой входа |
_start: | Метка, обозначающая начало вашего кода | CPU начинает выполнение здесь |
Тебе не нужно запоминать подробности. Просто знай, что в каждом main.asm перед твоим кодом должны быть эти две строки. Ты будешь использовать их в каждой программе.
Что произойдёт, если забыть системный вызов завершения?
Если не включить системный вызов завершения, CPU продолжит выполнять случайные данные, которые окажутся в памяти после вашего кода. Обычно это приводит к ошибке сегментации (сбою) или совершенно неожиданному поведению. Программа не завершится корректно.
Всегда завершай программу системным вызовом выхода.
Задание
Добавь системный вызов выхода с кодом завершения 5.
Код для вывода сообщения "Exiting with code 5" уже предоставлен. Пока тебе не нужно его понимать. Он будет рассмотрен в главе 5.
Твоя задача — только добавить системный вызов выхода в конце.
Попробуйте сами
section .data
msg db 'Exiting with code 5', 0x0a
msgLen equ $ - msg
section .text
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, msgLen
syscall
; TODO: Добавьте системный вызов выхода с кодом завершения 5
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Основы
1Машина
Что такое CPUПамятьРегистры против памятиКак работают инструкцииПаттерн двух файловАрхитектура x86-642Системы счисления
Почему двоичная система?Двоичные числаИз десятичной в двоичнуюПочему шестнадцатеричная система?Из шестнадцатеричной в десятичнуюИз десятичной в шестнадцатеричнуюASCII и Hex5Системный вызов Exit
Что такое системный вызов?Системный вызов Exit (60)Коды завершенияИтоги: корректное завершениеПотренируйтесь самостоятельно: Песочница Assembly