📌 Syscall
Syscall (System Call, системный вызов) — основной механизм обращения прикладного ПО к функциям ядра операционной системы: управление файлами, памятью, устройствами, сетями, процессами. Системный вызов обеспечивает безопасный переход из пользовательского режима (User mode) в привилегированный режим (Kernel mode) для выполнения сервисных функций, недоступных напрямую.
🧠 Как работает
Механика системного вызова
- Пользовательское приложение готовит параметры для вызова (обычно через регистры или стек).
 - Генерируется особая инструкция процессора (например, 
int 0x80,syscall,svc), вызывающая аппаратное переключение в режим ядра (Trap). - Ядро ОС получает номер системного вызова (Syscall Number) и параметры, выполняет необходимую функцию (например, Read, Write, Open, Close, Fork, Exec, Mmap).
 - Результат возвращается обратно в приложение, выполнение продолжается в пользовательском режиме.
 
Классический цикл
- User Mode: выполняется приложение, генерирует syscall.
 - Trap/Interrupt: CPU переключает в Kernel Mode.
 - Kernel Mode: ОС выполняет обработку syscall.
 - Return: возвращение управления и результата.
 
Архитектурные детали
- Номера системных вызовов фиксируются ABI (см. Syscall table, Syscall, Syscall).
 - На современных архитектурах есть специализированные инструкции:
 - Стандартный путь: параметры кладутся в определённые регистры (например, rax, rdi, rsi, …), номер syscall — в отдельный регистр.
 
Схема обработки системного вызова:
flowchart TB App["User App"] Params["Параметры (регистры/стек)"] Trap["Инструкция syscall/trap"] Kernel["Kernel (ОС)"] Handler["Syscall Handler"] Result["Результат"] App2["User App (продолжение)"] App --> Params Params --> Trap Trap --> Kernel Kernel --> Handler Handler --> Result Result --> App2
⚙️ Где применяется
- 
Все современные ОС: Linux, Windows, macOS, FreeBSD, RTOS и др.
 - 
Вызовы файловой системы (Read, Write, Open, Close), управление процессами (Fork, Exec, Wait), памятью (Mmap, Brk), IPC (Pipe, Socket, Msgqueue), сетевые стеки.
 - 
Контроль безопасности: sandbox, ограничения по SELinux, AppArmor, Seccomp.
 
✅ Преимущества
- 
Изоляция: пользовательский код не может напрямую обращаться к критическим ресурсам — безопасность ядра.
 - 
Стандартизация: унифицированный интерфейс работы с ОС и железом.
 - 
Гибкость: ядро может контролировать права, фильтровать и логировать вызовы.
 - 
Кроссплатформенность: слой совместимости для разных CPU/архитектур.
 
❌ Недостатки
- 
Задержки: каждый переход между режимами (user↔kernel) увеличивает время отклика (context switch, overhead).
 - 
Ограниченная производительность: массовые syscalls (например, read/write в цикле) замедляют I/O heavy приложения.
 - 
Платформозависимость: таблица номеров и calling convention меняется между платформами.
 - 
Эксплуатация: возможны атаки через некорректные параметры syscall (например, BOF, TOCTOU, race condition).
 - 
Ограниченная гибкость: только то, что реализовано в ядре, доступно через syscall-интерфейс.
 
🔗 Связанные технологии
Kernel, User mode, Kernel mode, Trap, Interrupt, Syscall, Syscall, Syscall table, Mmap, IO, Pipe, Socket, Seccomp, AppArmor, SELinux, RTOS
Резюме
Syscall — фундаментальный механизм взаимодействия приложений и ядра, позволяющий использовать системные ресурсы строго контролируемым образом. Все доступные внешнему коду функции ОС реализованы через syscalls. Переключение режима, защита памяти и контроль доступа обеспечивают безопасность, но влияют на производительность. Для современных OS — это критически важный компонент любой архитектуры.
Примеры кода
Прямой syscall на x86-64 Linux (ассемблер)
section .data
    msg db "Hello, syscall!", 10
    len equ $-msg
 
section .text
    global _start
 
_start:
    mov rax, 1        ; syscall number (sys_write)
    mov rdi, 1        ; file descriptor (stdout)
    mov rsi, msg      ; pointer to message
    mov rdx, len      ; message length
    syscall           ; invoke kernel
 
    mov rax, 60       ; syscall number (sys_exit)
    xor rdi, rdi      ; exit code 0
    syscallC: использование системного вызова через стандартную библиотеку
#include <unistd.h>
#include <sys/syscall.h>
 
int main() {
    const char* msg = "Hello, syscall!\n";
    syscall(SYS_write, 1, msg, 15); // SYS_write = номер системного вызова
    return 0;
}C: чтение списка системных вызовов из /proc
#include <stdio.h>
 
int main() {
    FILE* f = fopen("/proc/sys/kernel/osrelease", "r");
    char buf[256];
    fgets(buf, sizeof(buf), f);
    printf("OS Release: %s", buf);
    fclose(f);
    return 0;
}Источники: Linux man-pages, Intel® SDM, ARM Architecture Reference Manual, osdev.org, Википедия, kernel.org, habr.com, документация POSIX, исходники glibc/musl.