Ассемблер
Ассемблер — это программа, транслирующая язык ассемблера в машинный код.
Язык ассемблера — это низкоуровневый язык, предоставляющий более прямой доступ к аппаратным ресурсам компьютера по сравнению с высокоуровневыми языками. Каждая инструкция в языке ассемблера обычно соответствует одной машинной инструкции, что делает его близким к языку машинного кода.
Синтаксис
В этой статье используется синтаксис Intel на примере архитектуры x86-64.
Разновидности синтаксиса
Существует две основные разновидности синтаксиса для языка ассемблера: Intel и AT&T. Они различаются в основном в способе записи операндов и некоторых других деталях.
Синтаксис Intel чаще встречается при работе IBM-совместимыми архитектурами (например, x86 и x86-64), при использовании компиляторов от Intel и Microsoft.
Синтаксис AT&T чаще ассоциируется с миром UNIX-подобных систем. Например, он используется в ассемблерных программах в исходных текстах Linux.
Инструкция формируется из мнепоники (иногда называют опкод, от operation code) и какого-то количества операндов.
Например: mov eax, 5
; здесь mov
это мнемоника, а eax
и 5
— операнды.
Эта запись означает "поместить значение 5
в регистр eax
".
Одной мнемонике могут соответствовать несколько машинных команд. После компиляции они будут иметь разные машинные кода и, зачастую, разный размер.
Операнды могут быть трёх типов:
- непосредственный: значение, которое указано прямо в комадне
- регистровый: название регистра
- адресный: адрес ячейки (в т.ч. начало области памяти)
Адресный операнд всегда указывается в квадратных скобках []
.
Команды
Рассматривать все команды смысла нет, далее рассмотрены только основные.
Перемещение данных
mov <dst> <src>
(move)
Арифметические операции
-
add <dst> <src>
— складывает два операнда и сохраняет результат в целевом операнде (dst); эквивалентноdst = dst + src
-
sub <dst> <src>
(subtract) — вычитает второй операнд из первого и сохраняет результат в целевом операнде; эквивалентноdst = dst - src
-
inc <dst>
(increment) — увеличивает значение операнда на 1, эквивалентноdst = dst + 1
-
dec <dst>
(decrement) — уменьшает значение операнда на 1, эквивалентноdst = dst - 1
-
neg <dst>
(negate) — изменяет знак операнда; эквивалентноdst = -dst
-
mul
(multiply) -
div
(divide)
Логические операции
and
иtest
– побитовое "и"or
– побитовое "или"xor
– побитовое исключающее "или"cmp
(compare) – сравнение
Переходы
Безусловный переход обозначается командой jump
и имеет один операнд — метку,
к которой нужно перейти (под меткой понимается адрес инструкции).
Команд для переходов с условием значительно больше, но все они однотипны. Они также имеют один адресный операнд, но переход происходит только если выполнилось условие.
Эти команды выполняются в связке с другими (например cmp
). Предыдущие
команды каким-либо образом меняют флаговые регистры, на основе которых затем
происходит проверка истинности условия.
Например
cmp rax, rcx
jl label