====== Устройство и работа памяти центрального процессора (ЦП) ======
===== Введение =====
Центральный процессор (ЦП) выполняет команды, обрабатывает данные и управляет памятью. Одним из ключевых компонентов всей архитектуры является **система памяти**, которая обеспечивает хранение, доступ и обмен информацией между процессором, устройствами и программами.
Понимание того, как устроена память на уровне процессора, необходимо для:
* Оптимизации кода и производительности
* Реверс-инжиниринга и анализа уязвимостей
* Проектирования программ под низкоуровневые архитектуры
===== Общая модель памяти =====
С точки зрения ЦП, память можно разделить на следующие уровни:
* **Регистры** — самая быстрая и ближайшая память к ядру процессора
* **Кэш-память** (Cache): L1, L2, L3
* **Оперативная память (RAM)** — основное хранилище данных
* **Внешняя память (диск, SSD)** — долговременное хранилище
Каждый уровень иерархии работает быстрее, чем следующий, но объём уменьшается и стоимость возрастает.
===== 1. Регистры =====
^ Регистр ^ Назначение ^
| `EAX`, `RAX` | аккумулятор (результаты вычислений) |
| `EBX`, `RBX` | база (часто используется в указателях) |
| `ECX`, `RCX` | счётчик (используется в циклах, строковых операциях) |
| `EDX`, `RDX` | данные (вторичные значения) |
| `ESI`, `RSI`, `EDI`, `RDI` | источники и приёмники для операций |
| `ESP`, `RSP` | указатель стека |
| `EBP`, `RBP` | базовый указатель стека |
| `RIP` | указатель команд (только в x64) |
| Флаги (`EFLAGS`, `RFLAGS`) | хранят флаги результата: Zero, Carry, Overflow и т.д. |
**Регистры — это микросхемы внутри самого ядра ЦП**, они обеспечивают мгновенный доступ к данным.
===== 2. Кэш-память =====
Кэш — это быстрая SRAM-память, встроенная в процессор. Она уменьшает время доступа к данным из RAM.
^ Уровень ^ Расположение ^ Примерный размер ^ Задержка (циклы ЦП) ^
| L1 | Внутри ядра | 32–128 КБ | 3–4 |
| L2 | Внутри/рядом с ядром | 256 КБ – 1 МБ | 10–15 |
| L3 | Общая на несколько ядер | 2–64 МБ | 30–60 |
==== Политика кэширования ====
* **Write-back** — запись в кэш, RAM обновляется позже
* **Write-through** — запись сразу и в кэш, и в RAM
* **Cache line** — минимальная единица данных (обычно 64 байта)
==== Ассоциативность кэша ====
* **Direct-mapped** — каждая строка памяти попадает в один слот
* **Set-associative** — строки могут размещаться в любом из N слотов
* **Fully-associative** — строки могут размещаться где угодно
===== 3. Оперативная память (RAM) =====
RAM (DRAM) используется как основное рабочее пространство программ.
==== Основные характеристики: ====
* **Адресуемость**: в x64 системах — 2^64 байт (ограничено архитектурой и ОС)
* **Время доступа**: ~80–120 нс
* **Скорость передачи**: зависит от типа (DDR4, DDR5)
==== Виртуальная память ====
ОС предоставляет каждой программе собственное **виртуальное адресное пространство**, которое затем отображается в **физическую память**.
^ Компонент ^ Описание ^
| Page (страница) | Блок виртуальной памяти, обычно 4 КБ |
| Page Table | Таблица соответствий виртуальных и физических страниц |
| TLB (Translation Lookaside Buffer) | Кэш отображений виртуальных адресов в физические |
==== Сегментация и страничная организация ====
* **Сегментация** — логическая разбивка памяти на сегменты (использовалась в x86)
* **Страничная организация** — основа MMU (Memory Management Unit) в современных системах
===== 4. Внешняя память =====
Если данных слишком много для RAM, ОС может использовать **файл подкачки** или **pagefile**, хранящийся на SSD/HDD.
^ Тип ^ Назначение ^
| Swap/Pagefile | Используется при нехватке оперативной памяти |
| MMAP файлов | Отображение файла в память |
| Memory-mapped I/O | Обмен данными с периферией через память |
===== 5. Доступ к памяти =====
==== Адресация ====
* **Линейная**: последовательная адресация (x86, x64)
* **Сегментированная**: используется в реальном режиме x86
* **Физическая**: реальные адреса в DRAM
==== Типы доступа: ====
* **Чтение (read)** — перенос данных из памяти в регистр
* **Запись (write)** — перенос из регистра в память
* **Исполнение (execute)** — чтение инструкций из памяти
===== 6. Работа с памятью в ассемблере =====
==== Пример ====
mov eax, [ebp+8] ; чтение аргумента функции
mov [esp+4], eax ; запись в стек
call memcpy ; вызов функции с аргументами в памяти
==== Операции ====
* `mov`, `push`, `pop` — базовые операции чтения/записи
* `lea` — получение адреса (без чтения)
* `stos`, `lods`, `scas` — строковые операции
===== 7. Безопасность и память =====
==== Уязвимости: ====
* **Buffer Overflow** — выход за границы буфера
* **Use-after-free** — доступ к освобождённой памяти
* **Race conditions** — состояние гонки при совместном доступе
==== Защита: ====
* **DEP / NX bit** — запрет на выполнение кода в данных
* **ASLR** — рандомизация адресов
* **Stack canaries** — защитные значения в стеке
* **SMEP/SMAP** — запрет выполнения пользовательской памяти в ядре
===== 8. NUMA (Non-Uniform Memory Access) =====
NUMA — это архитектура многопроцессорных систем, при которой каждый процессор имеет **локальный доступ к "своей" памяти**, но также может обращаться к удалённой памяти других узлов (с большей задержкой).
^ Характеристика ^ Описание ^
| Узел NUMA (NUMA node) | Набор: ЦП + локальная память |
| Локальный доступ | Быстрый доступ к памяти своего узла |
| Удалённый доступ | Доступ к памяти другого узла через межсоединение (Interconnect) |
| Примеры | AMD EPYC, Intel Xeon, серверные платформы |
==== Зачем важно: ====
* Локальный доступ быстрее
* Неправильное распределение памяти (например, в многопоточных задачах) снижает производительность
* Используются **политики NUMA** (First touch, Interleaved, Bind memory to node)
==== Отображение в Linux: ====
numactl --hardware
==== Оптимизация ====
* Использование `numactl`
* Привязка потоков к NUMA-узлам
* Разделение данных по узлам
===== 9. Prefetching (Предзагрузка данных) =====
Prefetching — это механизм **предугадывания** того, какие данные потребуются процессору, и предварительной загрузки их из RAM в кэш.
==== Типы Prefetching: ====
^ Тип ^ Описание ^
| Hardware prefetch | Автоматически кэширует данные при линейном доступе |
| Software prefetch | Используется вручную с помощью инструкций (`prefetcht0`, `prefetchnta`) |
| Stride prefetch | Улавливает шаблоны с фиксированным шагом доступа |
| Adjacent cache line prefetch | Загрузка соседней строки кэша вместе с основной |
==== Пример в ассемблере: ====
prefetcht0 [esi+eax] ; загрузить строку в кэш из памяти
==== Роль в производительности: ====
* Уменьшает **кэш-промахи** (cache miss)
* Особенно полезен в **циклах**, **работе с массивами**, **потоках**
* Может ухудшать производительность, если предсказание неверное (pollution)
===== 10. Intel VT-x и память =====
Intel VT-x — это технология виртуализации, обеспечивающая аппаратную поддержку виртуальных машин. В контексте памяти VT-x влияет на **двойную трансляцию адресов**.
==== Две стадии адресации: ====
^ Этап ^ Описание ^
| Guest Virtual Address (GVA) | Адрес, используемый в ВМ (например, Linux) |
| Guest Physical Address (GPA) | Адрес внутри виртуальной машины |
| Host Physical Address (HPA) | Реальный адрес в памяти хоста |
==== Extended Page Tables (EPT): ====
* Позволяют гипервизору создавать **отображение GPA → HPA**
* Работают аналогично стандартным Page Tables
* **Кэшируются в TLB** и используются аппаратно
==== Зачем важно: ====
* Позволяет выполнять виртуальные ОС почти без потерь в производительности
* Обеспечивает изоляцию памяти между виртуальными машинами
* Используется в Hyper-V, KVM, VMware, VirtualBox и др.
===== 11. MMU (Memory Management Unit) на практике =====
MMU — аппаратный модуль, который преобразует **виртуальные адреса в физические**, реализует защиту памяти, контроль доступа и т.д.
==== Работа на практике: ====
^ Стадия ^ Действие ^
| Процессор генерирует виртуальный адрес | Например, при обращении к переменной |
| MMU ищет отображение в TLB | Если найдено — используется |
| Если нет — обращение к Page Table | Чтение соответствующей страницы |
| Проверка прав доступа | RWX-флаги, уровень привилегий |
| Генерация физического адреса | Передача на контроллер памяти (MC) |
==== Компоненты: ====
^ Компонент ^ Назначение ^
| TLB | Кэш отображений виртуальных адресов |
| Page Table | Основная таблица отображений |
| CR3 | Регистр, указывающий на Page Table |
| PTE | Page Table Entry — описание одной страницы |
==== Ошибки и исключения: ====
* **Page Fault (PF)** — отсутствует отображение или запрещён доступ
* **General Protection Fault (GPF)** — нарушение прав при доступе
==== Связь с безопасностью: ====
* **DEP/NX** реализуется через биты в PTE
* **ASLR** — случайное размещение виртуальных адресов
* **SMEP/SMAP** — защита ядра от пользовательских данных
===== 12. Заключение =====
Память ЦП — это **многоуровневая, иерархическая и сложная система**, включающая:
* регистры
* кэш-память (L1–L3)
* оперативную память с виртуализацией (MMU)
* NUMA и оптимизацию размещения данных
* механизм предвыборки (prefetching)
* аппаратную виртуализацию адресов (Intel VT-x)
Понимание всех этих слоёв особенно важно для:
* написания высокопроизводительных приложений
* отладки и анализа кода
* реверс-инжиниринга и безопасности
ЦП использует сложную иерархию памяти — от регистров до кэша и RAM, включая механизмы виртуализации и защиты. Это делает возможной как высокую производительность, так и изоляцию процессов.
===== Дополнительные ресурсы =====
* https://software.intel.com/sites/landingpage/IntrinsicsGuide/
* https://wiki.osdev.org/Memory_Management
* https://people.kernel.org/
* https://www.kernel.org/doc/html/latest/x86/mm.html
* https://developer.amd.com/resources/developer-guides-manuals/
===== Полезные ссылки =====
* https://en.wikipedia.org/wiki/CPU_cache
* https://wiki.osdev.org/Paging
* https://en.wikibooks.org/wiki/X86_Assembly
* https://wiki.osdev.org/Memory_Management
* https://learn.microsoft.com/en-us/windows/win32/memory/memory-protection-constants