Files
obsidian/Computer Science/Архитектуры/x86_64.md
T
roma-dxunvrs c0b8ac0043
deploy / Pull and Restart (push) Successful in 16s
fix PL, add x86 in CS
2026-09-29 21:49:51 +03:00

90 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Архитектура
- 64-битная (процессоры Intel / AMD)
- Ассемблер: `NASM`
- OC: Linux
- Размеры данных:
- `byte`
- `word` (два байта)
- `dword` (4 байта)
- `qword` (8 байт)
## Регистры общего назначения
Все 64-битные регистры начинаются с `R`. Их младшие части можно прочитать отдельно
#### База
- `RAX` (Accumulator) - аккумулятор, возвращаются результаты функций и номера сисколлов
- `RBX` (Base) - обычная переменная
- `RCX` (Counter) - счетчик циклов, 4-й аргумент функции, уничтожается сисколлом
- `RDX` (Data) - данные, 3-й аргумент функции, второе возвращаемое значение, хранит остаток при делении
#### Индексы и указатели
- `RDI` (Destination Index) - 1-й аргумент функции
- `RSI` (Source Index) - 2-й аргумент фукнции
- `RSP` (Stack Pointer) - указатель вершины стека
- `RBP` (Base Pointer) - указатель базы стекового кадра
#### Новые регистры
- `R8, R9` - 5-й и 6-й аргументы функций
- `R10, R11` - временные
- `R12-R15` - свободные переменные
#### Имена частей регистров
| *64 бита (qword)* | *32 бита (dword)* | *16 бит (word)* | *8 бит (byte)* |
| :---------------: | :---------------: | :-------------: | :------------: |
| `rax` | `eax` | `ax` | `al` |
| `rbx` | `ebx` | `bx` | `bl` |
| `rcx` | `ecx` | `cx` | `cl` |
| `rdx` | `edx` | `dx` | `dl` |
| `rdi` | `edi` | `di` | `dil` |
| `rsi` | `esi` | `si` | `sil` |
| `rsp` | `esp` | `sp` | `spl` |
| `rbp` | `ebp` | `bp` | `bpl` |
| `r8..15` | `r8..15d` | `r8..15w` | `r8..15b` |
## Соглашение о вызовах
1. Аргументы: `RDI`, `RSI`, `RDX`, `RCX`, `R8`, `R9`
2. Возврат значения: `RAX` и `RDX`
3. Сохранность регистров
- *Caller-saved* (портятся при вызове `call`): `RAX`, `RCX`, `RDX`, `RSI`, `RDI`, `R8-R11`. Обязанность запоминать их - на вызывающем
- *Callee-saved* (обязаны остаться неизменными): `RBX`, `RBP`, `RSP`, `R12-R15`. Обязанность вернуть их в исходное состояние - на функции
4. Выравнивание стека
- В момент `call` значение регистра `RSP` должно быть кратно 16
- При входе в функцию стек сдвинут адресом возврата, поэтому RSP % 16 == 8. Перед внутренним call нужно выровнять стек (сделать push или sub rsp, 8)
## Самые нужные сисколлы
Все сисколлы [тут](https://gitlab.se.ifmo.ru/programming-languages/cse-programming-languages-fall-2026/main/-/blob/master/docs/system-calls.md)
| Назначение | RAX | RDI (fd) | RSI (buffer) | RDX (size) | Возврат в RAX |
| :----------------------- | :--- | :----------- | :------------- | :---------- | :--------------------------------------------- |
| **Чтение (`sys_read`)** | `0` | `0` (stdin) | Адрес в памяти | Кол-во байт | Кол-во прочитанных байт (0 = EOF, <0 = ошибка) |
| **Запись (`sys_write`)** | `1` | `1` (stdout) | Адрес в памяти | Кол-во байт | Кол-во записанных байт |
| **Выход (`sys_exit`)** | `60` | Код возврата | - | - | Процесс завершается |
## Самые нужные инструкции
#### Перемещение данных
- `mov A, B` - скопировать B в A
- `movzx` - скопировать байт B в регистр A и заполнить старшие биты нулями
#### Математика
- `add A, B` / `sub A, B` - сложение / вычитание `A = A +/- B`
- `inc A` / `dec A` - инкремент / декремент
- `neg A` - `A = -A`
- `imul A, B` - знаковое умножение `A = A * B`
- `mul B` - беззнаковое умножение, умножает `RAX` на B. Старшая часть результата в `RDX`, младшая - в `RAX` (результат - `RDX:RAX`)
- `div B` - беззнаковое деление. Делит `RDX:RAX` на B. Частное в `RAX`, остаток в `RDX`
#### Логика
- `and`, `or`, `not` - побитовое И, ИЛИ, НЕ
- `xor A, B` - исключающее ИЛИ (`xor rax, rax` - быстрый способ обнулить регистр)
- `test A, B` - побитовое И без сохранения результата (только ставит флаги) - лучший способ проверить регистр на ноль
#### Ветвление и переходы
- `cmp A, B` - сравнивает A и B, ставит флаги
- `jmp метка` - безусловный переход
- `je` / `jne` (или `jz` / `jnz`) - прыжок, если `Z = 1` / `Z = 0`
- Дли знаковых чисел
- `jl` / `jle` (Less / Less or Equal) - меньше / меньше или равно
- `jg` / `jge` (Greater / Greater or Equal) - больше / больше или равно
- `js` / `jns` (Sign) - отрицательное / положительное (флаг `S`)
- Для беззнаковых чисел:
- `jb` / `jbe` (Below / Below or Equal) - меньше / меньше или равно
- `ja / jae` (Above / Above or Equal) - больше / больше или равно
- Для переполнений
- `jc` / `jnc` (Carry)
- `jo` / `joc` (Overflow)
#### Работа со стеком
Растет как в БЭВМ (в сторону уменьшения адресов)
- `push A` - кладет 8 байт на стек (`rsp -= 8, [rsp] = A`)
- `pop A` - достает 8 байт со стека (`A = [rsp], rsp += 8`)
- `sub rsp, 24` - выделить буфер на 24 байта
- `add rsp, 24` - освободить буфер