6.7 KiB
6.7 KiB
Архитектура
- 64-битная (процессоры Intel / AMD)
- Ассемблер:
NASM - OC: Linux
- Размеры данных:
byteword(два байта)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 |
Соглашение о вызовах
- Аргументы:
RDI,RSI,RDX,RCX,R8,R9 - Возврат значения:
RAXиRDX - Сохранность регистров
- Caller-saved (портятся при вызове
call):RAX,RCX,RDX,RSI,RDI,R8-R11. Обязанность запоминать их - на вызывающем - Callee-saved (обязаны остаться неизменными):
RBX,RBP,RSP,R12-R15. Обязанность вернуть их в исходное состояние - на функции
- Caller-saved (портятся при вызове
- Выравнивание стека
- В момент
callзначение регистраRSPдолжно быть кратно 16 - При входе в функцию стек сдвинут адресом возврата, поэтому RSP % 16 == 8. Перед внутренним call нужно выровнять стек (сделать push или sub rsp, 8)
- В момент
Самые нужные сисколлы
Все сисколлы тут
| Назначение | 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 в Amovzx- скопировать байт B в регистр A и заполнить старшие биты нулями
Математика
add A, B/sub A, B- сложение / вычитаниеA = A +/- Binc A/dec A- инкремент / декрементneg A-A = -Aimul A, B- знаковое умножениеA = A * Bmul 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- освободить буфер