01. Прикладной программный интерфейс
Лекция №1. Прикладной программный интерфейс
Курс: Системное программирование (2026–2027)
Учебная программа: 2025, регистрационный № УП-46/2025Пп/уч
Специальность переподготовки: 9-09-0612-02 «Программное обеспечение информационных систем»
Квалификация: Инженер-программист
Тема по программе: Тема 1. Прикладной программный интерфейс (4 академических часа)
Формируемые компетенции: СП-21, СП-22
Введение и цели занятия
📌 Слайд 1: Тема 1. Прикладной программный интерфейс
Системное программирование формирует фундамент квалификации инженера-программиста. Прикладной разработчик оперирует бизнес-логикой и абстракциями высокоуровневых сред исполнения. Системный разработчик управляет аппаратными ресурсами вычислительной машины через интерфейсы операционной системы.
Цель настоящей лекции — разобрать внутреннее устройство прикладного программного интерфейса (API), принципы разграничения привилегий между пользователем и ядром, аппаратный механизм системных вызовов, а также сравнить нативные парадигмы ОС Linux и Windows.
📌 Слайд 2: План лекции
Учебные вопросы лекции:
- Архитектурные уровни вычислительной системы и место API.
- Аппаратная защита памяти и кольца привилегий процессора (Ring 0 и Ring 3).
- Механизм прерываний и эволюция системного вызова (от
int 0x80кsyscall/sysret). - Нативный API операционных систем: сопоставление подходов Linux (POSIX, libc) и Windows (WinAPI, Native API ntdll).
- Стратегии обработки и локализации ошибок (
errnoпротивGetLastError). - Современный инструментарий разработки, отладки и трассировки системного ПО (GCC, Clang, MSVC, GDB, WinDbg, strace, ProcMon).
1. Архитектурные уровни вычислительной системы и понятие нативного API
📌 Слайд 3: Архитектурные уровни вычислительной системы
Вычислительная система строится по иерархическому принципу абстракций. Каждый вышележащий уровень скрывает технические детали нижележащего, предоставляя стандартизированный протокол взаимодействия:
- Аппаратный уровень (Hardware): центральный процессор, оперативная память, постоянные накопители, сетевые адаптеры, контроллеры прерываний и шины обмена данными.
- Ядро операционной системы (Operating System Kernel): монопольно управляет оборудованием, изолирует программы друг от друга, распределяет процессорное время и страницы оперативной памяти.
- Интерфейс системных вызовов (System Call Interface, SCI): формальная граница между непривилегированным пользовательским кодом и привилегированным ядром.
- Стандартные системные библиотеки и платформенный API: библиотеки языка Си (glibc, musl) в Linux и подсистемные динамические библиотеки (kernel32.dll, user32.dll) в Windows.
- Прикладное программное обеспечение (Applications): пользовательские процессы, выполняющие прикладные вычисления.

📌 Слайд 4: Понятие прикладного программного интерфейса (API)
Прикладной программный интерфейс (Application Programming Interface, API) — это задокументированный контракт взаимодействия между вызывающей программой и поставщиком сервиса (операционной системой, библиотекой или сетевым сервисом). Контракт включает:
- состав и сигнатуры доступных функций,
- типы передаваемых и возвращаемых параметров,
- константы и структуры данных,
- соглашения об обработке исключительных ситуаций и ошибок.
В системном программировании ключевым является понятие нативного API (Native API). Нативный API взаимодействует с операционной системой на уровне машинного кода целевой архитектуры без промежуточных виртуальных машин, интерпретаторов и эмуляторов.
Различают два родственных понятия:
- API (Application Programming Interface): исходный программный контракт на уровне исходного текста (заголовочные файлы
.h, имена функций, макросы). Код, написанный под строгий стандарт API (например, POSIX.1), переносим между различными ОС путем перекомпиляции. - ABI (Application Binary Interface): бинарный контракт на уровне машинного кода. ABI определяет размер и выравнивание типов данных в памяти, схему передачи параметров через регистры процессора, порядок размотки стека и формат исполняемых файлов (ELF в Linux, PE/COFF в Windows). Бинарная совместимость гарантирует, что уже скомпилированный модуль будет исполняться без пересборки.
2. Аппаратная изоляция и кольца защиты процессора
📌 Слайд 5: Кольца защиты процессора (Ring 0 и Ring 3)
Безопасность и отказоустойчивость современных ОС опираются на аппаратную поддержку со стороны центрального процессора. Начиная с архитектуры Intel 80286 и 80386, микропроцессоры x86/x64 поддерживают концепцию иерархических уровней привилегий (кольца защиты, Protection Rings).
Аппаратура поддерживает 4 кольца (от Ring 0 до Ring 3):
- Ring 0 (Supervisor Mode / Kernel Mode): максимальный уровень привилегий. Код ядра имеет прямой доступ ко всему физическому адресному пространству памяти, портам ввода-вывода и управляющим регистрам ЦПУ.
- Ring 1 и Ring 2: промежуточные уровни, изначально предназначавшиеся для служб ОС и драйверов. В современных ОС общего назначения (Linux, Windows, macOS, FreeBSD) не используются ради скорости и универсальности межплатформенного портирования.
- Ring 3 (User Mode): минимальный уровень привилегий. Прикладной код лишен прямого доступа к оборудованию, изолирован в собственном виртуальном адресном пространстве и не может выполнять критические инструкции процессора.
Текущий уровень привилегий процессора определяется битами CPL (Current Privilege Level) в селекторе сегмента кода CS (Code Segment). Значение 00b соответствует Ring 0, а 11b — Ring 3.
📌 Слайд 6: Привилегированные инструкции и барьер изоляции
При попытке кода в режиме Ring 3 выполнить привилегированную инструкцию центральный процессор блокирует выполнение и генерирует исключение общей защиты (General Protection Fault, прерывание вектор #GP, код 13).
К привилегированным инструкциям относятся:
- прямое управление контроллером прерываний:
cli(запрет маскируемых прерываний),sti(разрешение); - перевод процессора в состояние энергосберегающего ожидания:
hlt; - изменение управляющих регистров:
mov cr0, reg,mov cr3, reg(загрузка адреса корневой таблицы страниц памяти),mov cr4, reg; - чтение и запись модельно-зависимых регистров:
rdmsr,wrmsr; - модификация таблиц дескрипторов сегментов и прерываний:
lgdt,lidt,ltr.
Аппаратная защита оперативной памяти реализуется блоком управления памятью (Memory Management Unit, MMU). Каждая запись в таблицах страниц (Page Table Entry, PTE) содержит служебные биты:
- U/S (User / Supervisor): при сброшенном бите доступ к странице разрешен только из Ring 0. При попытке чтения или записи из Ring 3 процессор генерирует отказ страницы (Page Fault,
#PF, вектор 14). - R/W (Read / Write): разрешение модификации данных.
- NX / XD (No-Execute / Execute-Disable): запрет исполнения кода из страниц данных (защита от атак переполнения стека и кучи).
Таким образом, прикладная программа физически не может самостоятельно обратиться к диску, отправить сетевой пакет или прочитать память соседнего процесса. Единственный легальный путь взаимодействия с внешним миром — запрос к ядру через системный вызов.
3. Механизм прерываний и системные вызовы
📌 Слайд 7: Механизм прерываний в вычислительных системах
Прерывание (Interrupt) — это аппаратный сигнал процессору, требующий немедленного приостановления текущего потока команд и перехода на специальную подпрограмму обработки (Interrupt Service Routine, ISR).
Прерывания делятся на три категории:
- Аппаратные прерывания (Hardware Interrupts / Asynchronous): генерируются внешними контроллерами независимо от текущей выполняемой инструкции ЦПУ (нажатие клавиши клавиатуры, поступление пакета в сетевую карту, сигнал системного таймера APIC).
- Исключения процессора (Processor Exceptions / Synchronous): генерируются самим ЦПУ при возникновении нестандартных условий в процессе исполнения команды:
- Faults (Ошибки): обнаруживаются до выполнения инструкции, могут быть исправлены ядром с повторным запуском команды (например, Page Fault при подкачке страницы с диска).
- Traps (Ловушки): фиксируются сразу после выполнения инструкции (например, точка останова отладчика
int 3). - Aborts (Аварии): неустранимые аппаратные сбои (Machine Check Exception).
- Программные прерывания (Software Interrupts): вызываются кодом преднамеренно через специальную команду процессора (
int N). Именно программные прерывания исторически служили механизмом перехода в ядро.
📌 Слайд 8: Таблица дескрипторов прерываний (IDT)
В защищенном и длинном режимах работы процессоров x86/x64 маршрутизация всех прерываний выполняется через Таблицу дескрипторов прерываний (Interrupt Descriptor Table, IDT).
Таблица содержит массив из 256 дескрипторов (шлюзов), адрес которых загружается в регистр IDTR инструкцией lidt:
- Шлюзы прерываний (Interrupt Gates): при входе в обработчик автоматически сбрасывают флаг
IFв регистреRFLAGS, блокируя другие маскируемые прерывания. - Шлюзы ловушек (Trap Gates): не модифицируют флаг
IF.
Каждый дескриптор в IDT задает:
- сегмент кода ядра (
CS) и смещение точки входа обработчика; - уровень привилегий шлюза (DPL, Descriptor Privilege Level). Если DPL шлюза равен 0, инструкция
int N, вызванная из Ring 3, приведет к исключению#GP. Для разрешения системных вызовов DPL шлюза выставляется в 3.
📌 Слайд 9: Эволюция системных вызовов: int 0x80 против syscall
Исторически системные вызовы в 32-разрядных ОС реализовывались через программные прерывания:
- В Linux x86 применялся вектор
int 0x80. - В Windows x86 применялся вектор
int 0x2e.
Недостаток программного прерывания — высокие накладные расходы. При вызове int 0x80 процессор выполнял десятки циклов проверки сегментных дескрипторов в GDT, считывал IDT, проверял права DPL/CPL, сохранял в стек старые значения SS, ESP, EFLAGS, CS, EIP и считывал стек ядра из сегмента состояния задачи (TSS). Переход занимал 100–150 тактов процессора на каждый вызов.
Для устранения этой проблемы производители процессоров разработали специализированные инструкции быстрого системного вызова:
- Инструкции SYSENTER / SYSEXIT (Intel x86): целевые адреса и селекторы сегментов заранее заносятся операционной системой в регистры MSR (Model-Specific Registers)
IA32_SYSENTER_CS,IA32_SYSENTER_ESP,IA32_SYSENTER_EIP. - Инструкции SYSCALL / SYSRET (AMD64 / Intel 64): стандарт для всех современных 64-битных ОС. Точка входа в ядро настраивается в регистре
IA32_LSTAR(Long System Target Address Register, MSR0xC0000082).
Инструкция syscall не обращается к таблице IDT и не обращается к оперативной памяти при смене контекста:
- Сохраняет адрес следующей пользовательской инструкции в регистр
RCX. - Сохраняет регистр флагов
RFLAGSв регистрR11. - Маскирует флаги согласно регистру
IA32_FMASK(в частности, отключает внешние прерывания). - Загружает в
RIPадрес точки входа ядра из регистраIA32_LSTAR. - Устанавливает CPL = 0 (Ring 0).
Накладные расходы снизились до 10–20 тактов, обеспечив высокую производительность системного ввода-вывода.

4. Архитектура нативного API: сопоставление Linux и Windows
📌 Слайд 10: Реализация системных вызовов в ОС Linux
В операционной системе Linux системные вызовы представляют собой первичный публичный интерфейс ядра. Ядро гарантирует обратную бинарную совместимость: программа, скомпилированная под ядро Linux 2.6 двадцать лет назад, продолжает функционировать на современном ядре Linux 6.x.
Соглашение о вызовах Linux на архитектуре x86-64 регламентируется стандартом System V AMD64 ABI:
- Номер системного вызова передается в регистре
RAX(например, 0 —read, 1 —write, 2 —open, 3 —close, 60 —exit). - Аргументы функции (до 6 параметров) передаются в строгой последовательности через регистры:
- Первый аргумент:
RDI - Второй аргумент:
RSI - Третий аргумент:
RDX - Четвертый аргумент:
R10(внимание: компиляторы языка Си используютRCX, но при системном вызовеRCXзатирается аппаратурой, поэтому ядро используетR10) - Пятый аргумент:
R8 - Шестой аргумент:
R9
- Первый аргумент:
- Результат вызова возвращается в регистре
RAX.
Рассмотрим ассемблерную реализацию прямого вызова без использования стандартных библиотек:
1; Прямой системный вызов write(1, msg, 14) на ассемблере NASM (Linux x86-64)
2global _start
3
4section .data
5 msg db "Hello, System!", 0x0A
6 len equ $ - msg
7
8section .text
9_start:
10 mov rax, 1 ; номер sys_write
11 mov rdi, 1 ; дескриптор stdout (1)
12 mov rsi, msg ; адрес буфера
13 mov rdx, len ; размер данных в байтах
14 syscall ; переход в ядро
15
16 mov rax, 60 ; номер sys_exit
17 xor rdi, rdi ; код возврата 0
18 syscall
В реальных программах на языке Си разработчик не пишет ассемблерный код вручную. Стандартная библиотека GNU C Library (glibc) или альтернативная компактная musl предоставляет тонкие Си-обертки (wrappers), объявляемые в заголовках <unistd.h>, <fcntl.h>, <sys/stat.h>.
📌 Слайд 11: Архитектура Windows: Win32 API и Native API
Архитектура операционной системы Windows принципиально отличается от монолитной структуры Linux. В Windows интерфейс системных вызовов ядра не является публичным контрактом. Microsoft не гарантирует постоянство номеров системных вызовов: таблица SSDT (System Service Descriptor Table) меняется между выпусками ОС и сервис-паками.
Архитектура Windows базируется на концепции подсистем окружения (Environment Subsystems):
- Win32 Subsystem (Windows API): официальный стабильный программный интерфейс. Реализуется набором динамических библиотек пользовательского режима:
kernel32.dll/KernelBase.dll— базовые службы ОС: процессы, потоки, память, файлы, синхронизация.user32.dll— окна, диалоги, оконные сообщения, ввод с мыши и клавиатуры.gdi32.dll— графический интерфейс устройств (Graphics Device Interface), шрифты, примитивы рисования.advapi32.dll— реестр Windows, службы (Services), учетные записи и токены безопасности.
- Native API (
ntdll.dll): низкоуровневая прослойка пользовательского режима. Содержит функции с префиксамиNt...иZw...(NtCreateFile,NtAllocateVirtualMemory). Именно функцииntdll.dllвыполняют инструкциюsyscallдля перехода в режим ядра. Этот слой считается внутренним и не подлежит прямому вызову в обычном прикладном софте. - Ядро Windows (
ntoskrnl.exe): исполняет системные службы, взаимодействует с диспетчером объектов (Object Manager), диспетчером памяти и драйверами через уровень абстракции от оборудования (HAL,hal.dll).

📌 Слайд 12: Особенности WinAPI: Дескрипторы HANDLE и Unicode
В WinAPI ключевую роль играют две системные концепции:
1. Дескрипторы ресурсов (HANDLE)
В отличие от целочисленных файловых дескрипторов Linux (int fd), в Windows системные ресурсы идентифицируются непрозрачным типом HANDLE. HANDLE представляет собой псевдоуказатель (индекс во внутренней таблице дескрипторов процесса).
Через HANDLE адресуются:
- файлы и каталоги,
- процессы и потоки,
- объекты синхронизации (мьютексы, семафоры, события),
- сопоставления памяти (file mappings),
- токены доступа.
После завершения работы объект ядра обязательно закрывается системным вызовом CloseHandle(h). Неосвобожденный дескриптор приводит к утечке ресурсов в ядре.
2. Поддержка кодировок ANSI и Unicode
Функции WinAPI, принимающие строки, существуют в двух вариантах:
- Вариант A (ANSI): однобайтовые строки
char*, работающие через текущую кодовую страницу системы (например,CreateFileA). - Вариант W (Wide / Unicode): строки UTF-16LE на базе двухбайтового типа
wchar_t*(например,CreateFileW).
Внутреннее ядро Windows всегда работает в Unicode (UTF-16). Любой вызов функции с суффиксом A приводит к скрытому выделению памяти, перекодированию строки в UTF-16, вызову соответствующей функции W и освобождению буфера. Современное системное программирование под Windows ведется исключительно с использованием функций Unicode (W).
5. Стратегии обработки системных ошибок
📌 Слайд 13: Обработка системных ошибок в Linux
Системный вызов ядра Linux при возникновении сбоя возвращает отрицательное число в диапазоне от -4095 до -1. Модуль этого числа соответствует стандартизированному коду ошибки POSIX (например, -2 означает -ENOENT, файл не найден).
Библиотечная обертка glibc при получении отрицательного значения выполняет следующие действия:
- Инвертирует знак кода ошибки:
val = -res. - Записывает этот код в потоко-локальную переменную
errno. - Возвращает прикладной программе маркер ошибки — значение
-1(для целочисленных функций) илиNULL(для функций, возвращающих указатели).
1#include <stdio.h>
2#include <fcntl.h>
3#include <unistd.h>
4#include <errno.h>
5#include <string.h>
6
7int main(void) {
8 int fd = open("/etc/shadow", O_RDONLY);
9 if (fd == -1) {
10 // Сохраняем errno сразу, пока последующие вызовы его не затерли
11 int err = errno;
12 fprintf(stderr, "Ошибка открытия: %s (код ошибки: %d)\n",
13 strerror(err), err);
14 return 1;
15 }
16 close(fd);
17 return 0;
18}
Важно: Переменная
errnoсохраняет свое значение до следующего ошибочного системного вызова. Успешные вызовы не обнуляютerrno. В многопоточных программахerrnoобъявляется как макрос, раскрывающийся в вызов функции(*__errno_location()), возвращающей адрес ячейки в локальном хранилище текущего потока (Thread-Local Storage, TLS). Это исключает гонки потоков при параллельной фиксации ошибок.
📌 Слайд 14: Обработка системных ошибок в Windows
В Windows системный уровень ядра возвращает 32-битный статус NTSTATUS (например, 0xC0000034 — STATUS_OBJECT_NAME_NOT_FOUND). Библиотека подсистемы (KernelBase.dll) преобразует его в 32-битный код ошибки Win32 (ERROR_FILE_NOT_FOUND, код 2) с помощью функции RtlNtStatusToDosError.
Код ошибки сохраняется в структуре TEB (Thread Environment Block) текущего потока в поле LastErrorValue. Прикладной код извлекает ошибку вызовом функции GetLastError(), а текстовое описание ошибки формируется системной функцией FormatMessageW:
1#include <windows.h>
2#include <stdio.h>
3
4int main(void) {
5 HANDLE hFile = CreateFileW(
6 L"C:\\non_existent_file.txt",
7 GENERIC_READ,
8 FILE_SHARE_READ,
9 NULL,
10 OPEN_EXISTING,
11 FILE_ATTRIBUTE_NORMAL,
12 NULL
13 );
14
15 if (hFile == INVALID_HANDLE_VALUE) {
16 DWORD errCode = GetLastError();
17 LPWSTR msgBuffer = NULL;
18
19 FormatMessageW(
20 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
21 NULL,
22 errCode,
23 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
24 (LPWSTR)&msgBuffer,
25 0,
26 NULL
27 );
28
29 wprintf(L"Сбой CreateFileW. Код: %lu, Описание: %s", errCode, msgBuffer);
30 LocalFree(msgBuffer);
31 return 1;
32 }
33
34 CloseHandle(hFile);
35 return 0;
36}

6. Современный инструментарий системного разработчика
📌 Слайд 15: Сборочные цепочки и компиляторы
Разработка системно-ориентированного ПО предъявляет строгие требования к сборочному инструментарию:
- GNU Compiler Collection (GCC): промышленный стандарт в мире UNIX/Linux. Отличается глубокой поддержкой низкоуровневых расширений языка Си (встроенный ассемблер
__asm__, атрибуты секций__attribute__((section)), указание выравнивания памяти). - Clang / LLVM: модульная компиляторная инфраструктура. Обеспечивает детальный статический анализ, интеграцию с санитайзерами памяти (AddressSanitizer, ThreadSanitizer) и быструю генерацию промежуточного представления (LLVM IR).
- Microsoft Visual C++ (MSVC): основной инструмент экосистемы Windows. Интегрирован с отладчиком Visual Studio, предоставляет богатые директивы
#pragmaи intrinsic-функции для прямого доступа к инструкциям процессора без ассемблерных вставок (__readgsqword,_mm_pause,_InterlockedIncrement).
Рекомендуемые флаги компиляции системного кода (GCC/Clang):
-Wall -Wextra -Wpedantic— строгий контроль предупреждений;-O2— базовая оптимизация без искажения последовательности обращений к памяти;-fno-omit-frame-pointer— сохранение базового указателя фрейма стека (RBP), необходимое для точной трассировки стека отладчиками и утилитами профилирования;-g3— включение расширенной отладочной информации DWARF, включая макроопределения.
📌 Слайд 16: Системные отладчики: GDB и WinDbg
Отладка системного ПО принципиально отличается от прикладной. Системному инженеру требуется анализировать регистры процессора, отображения виртуальных страниц и структуры ядра.
GDB (GNU Debugger) под Linux:
- Позволяет подключаться к исполняемому процессу, анализировать файлы аварийных дампов памяти (Core Dumps).
- Управление точками останова по инструкциям:
b *0x401120,layout asm,layout regs. - Просмотр памяти по адресам:
x/16xg $rsp(вывод 16 восьмибайтовых слов со стека в шестнадцатеричном виде). - Дизассемблирование машинного кода:
disassemble /r main.
WinDbg (Windows Debugger):
- Профессиональный инструмент анализа пользовательского режима и режима ядра Windows.
- Подключение отладочных символов с сервера символов Microsoft (
.sympath srv*https://msdl.microsoft.com/download/symbols). - Анализ структур ядра и структур подсистем:
!peb(Process Environment Block),!teb(Thread Environment Block),!gle(вывод последней ошибкиGetLastError). - Анализ аварийных дампов падения (
minidump,memory.dmp).
📌 Слайд 17: Инструменты динамической трассировки: strace и ProcMon
Динамическая трассировка системных вызовов позволяет исследовать поведение программ без наличия исходного кода:
1. Утилита strace в Linux
Использует системный вызов ядра ptrace. Перехватывает каждый вход в системный вызов и выход из него, расшифровывая аргументы, строковые буферы, битовые маски и коды ошибок:
1# Запуск трассировки команды ls с выводом только файловых операций
2strace -e trace=openat,read,write,close ls -la
3
4# Подключение к уже работающему процессу по его PID с таймстемпами
5strace -tt -p 14205 -o trace_output.log
6
7# Сбор статистики по времени и количеству системных вызовов
8strace -c ./my_program
Пример протокола трассировки:
1openat(AT_FDCWD, "config.json", O_RDONLY) = 3
2read(3, "{\n \"host\": \"localhost\"\n}\n", 1024) = 28
3close(3) = 0
4write(1, "Config loaded\n", 14) = 14
2. Process Monitor (ProcMon) в Windows
Графическая утилита из состава Microsoft Sysinternals Suite. Работает через специализированный драйвер файловой системы и фильтр системных событий ядра. Позволяет в реальном времени протоколировать:
- все обращения к файловой системе (CreateFile, ReadFile, CloseFile);
- операции с реестром Windows (RegOpenKey, RegQueryValue);
- операции с процессами, потоками и сетевыми сокетами;
- стек вызовов (Call Stack) вплоть до конкретного модуля и адреса в памяти.
📌 Слайд 18: Резюме лекции
Основные итоги:
- Нативный API обеспечивает прямое взаимодействие прикладных программ с ядром вычислительной системы без промежуточных виртуальных сред.
- Аппаратные кольца защиты (Ring 0 и Ring 3) в связке с блоком MMU гарантируют изоляцию памяти и предотвращают сбои оборудования из-за ошибок в прикладных процессах.
- Эволюция системных вызовов перешла от медленных программных прерываний (
int 0x80) к быстрым аппаратным инструкциям (syscall/sysret), настроенным через модельно-зависимые регистры (MSR). - Linux предоставляет стабильный и документированный интерфейс прямых системных вызовов (System V ABI), обернутый библиотекой Си.
- Windows скрывает системные вызовы за фасадом стабильных подсистемных DLL (WinAPI), изолируя разработчика от нестабильного Native API ядра.
- Обработка системных ошибок в Linux опирается на потоко-локальную переменную
errno, а в Windows — на полеLastErrorValueв структуреTEB, опрашиваемое функциейGetLastError().
📌 Слайд 19: Вопросы для самопроверки
- В чем заключается принципиальное различие между понятиями API и ABI?
- Какие аппаратные механизмы процессора и MMU предотвращают доступ пользовательской программы к адресному пространству ядра?
- Почему инструкция
syscallвыполняется существенно быстрее программного прерыванияint 0x80? - Какие регистры процессора используются для передачи номера вызова и аргументов в Linux на архитектуре x86-64?
- Почему корпорация Microsoft не рекомендует напрямую вызывать системные функции из
ntdll.dll? - Что представляет собой дескриптор
HANDLEв Windows и почему его необходимо закрывать? - Каким образом потокобезопасность переменной
errnoв Linux обеспечивается на многопоточных системах? - Для решения каких задач системный инженер применяет утилиты
straceи Process Monitor?
📌 Слайд 20: Литература и рекомендуемые ресурсы
Литература по курсу:
- Современные операционные системы (4-е изд.) — Таненбаум Э., Бос Х. СПб.: Питер, 2021. 1119 с.
- Устройство и функционирование OC Windows. Практикум к курсу «Операционные системы» — Коньков К. А. М.: Бином, 2008. 208 с.
- Операционные системы (2-е изд.) — Гордеев А. В. СПб.: Питер, 2009. 415 с.
- Системное программирование: методические указания по выполнению лабораторных работ — Бизюк А. Н., Соколова А. С. Витебск: УО «ВГТУ», 2024.
- Официальная документация Windows API — https://learn.microsoft.com/en-us/windows/win32/api/
- Справочник системных вызовов Linux (man-pages) — https://man7.org/linux/man-pages/dir_section_2.html