Архитектура x86-64 и цикл исполнения
Урок собирает общую картину: из чего состоит процессор и как команды превращаются в действия.
Архитектура набора команд (ISA) — это «контракт» между железом и программистом: список команд, регистров и правил, на которые можно опираться.
Из чего состоит процессор для нас
Чтобы писать на ассемблере, не нужно знать транзисторы. Достаточно модели из нескольких блоков:
- Регистры — крошечные сверхбыстрые ячейки внутри процессора (rax, rbx и др.). Их единицы, и в них идёт вся работа.
- АЛУ (арифметико-логическое устройство) — складывает, вычитает, сравнивает, делает
and/or. - Память (RAM) — огромный массив байтов снаружи процессора, медленнее регистров.
- Регистр флагов RFLAGS — хранит результат последнего сравнения (был ли ноль, перенос, знак).
Почему регистры, а не сразу память
Регистр читается за доли наносекунды, обращение к RAM — в десятки раз дольше. Поэтому философия ассемблера такая: загрузи данные из памяти в регистры, обработай в регистрах, выгрузи результат обратно. Почти каждая арифметическая команда работает с регистрами, а не напрямую с памятью.
Цикл исполнения на примере
Возьмём программу из трёх команд и проследим состояние регистра rax:
mov rax, 10 ; шаг 1
add rax, 5 ; шаг 2
sub rax, 3 ; шаг 3Изменение значения шаг за шагом:
| Шаг | Команда | rax после |
| 1 | mov rax, 10 | 10 |
| 2 | add rax, 5 | 15 |
| 3 | sub rax, 3 | 12 |
На каждом шаге процессор выбирает команду по адресу RIP, декодирует её, выполняет в АЛУ и сдвигает RIP дальше. Эту же модель удобно проверять на Python, имитируя регистр обычной переменной.
rax = 10
print("start :", rax)
rax = rax + 5 # add rax, 5
print("add 5 :", rax)
rax = rax - 3 # sub rax, 3
print("sub 3 :", rax)Вывод:
start : 10 add 5 : 15 sub 3 : 12
Как работает под капотом
Между процессором и RAM стоят несколько уровней кэша (L1, L2, L3). Когда вы делаете mov rax, [адрес], процессор сначала ищет данные в L1; если не нашёл — спускается ниже, вплоть до RAM. Поэтому обращения к памяти бывают «дешёвыми» и «дорогими», хотя в ассемблере выглядят одинаково. Это объясняет, почему один и тот же алгоритм с другим порядком доступа к памяти может работать в разы быстрее.
Частые ошибки
- Считать память и регистры одним и тем же. Регистров мало и они быстры; память велика и медленна. Команды работают по-разному с тем и другим.
- Игнорировать флаги. После арифметики и сравнений RFLAGS меняется автоматически — именно от него зависят условные переходы.
- Ждать «оператора цикла». В процессоре нет
while— цикл собирается вручную из сравнения и перехода (об этом будет отдельный раздел).
Итог
- Процессор для нас — это регистры, АЛУ, флаги и память снаружи.
- Работа идёт в регистрах, потому что они в десятки раз быстрее RAM.
- Команды исполняются в цикле fetch–decode–execute, RIP ведёт указатель.
- RFLAGS хранит результат последней операции и управляет переходами.