### Содержание - [[#ADD]] - [[#CALL]] - [[#CMP]] - [[#DEC]] - [[#DIV]] - [[#ENTER]] - [[#IDIV]] - [[#IMUL]] - [[#INC]] - [[#JMP]] - [[#LEA]] - [[#LEAVE]] - [[#MOV]] - [[#MUL]] - [[#NEG]] - [[#POP]] - [[#PUSH]] - [[#RET]] - [[#SAL/SAR/SHL/SHR|SHIFT]] - [[#SUB]] - [[#SYSCALL]] - [[#TEST]] - [[#XOR]] ### ADD `add , ` добавляет значение операнда `` к значению операнда `` и записывает результат в операнд ``. #### Комбинации операндов `` - `` - регистр - регистр или ячейка памяти - регистр или ячейка памяти - регистр - регистр - явно заданный операнд - `al/ax/eax/rax` - явно заданный операнд #### Флаги Ставит OF, SF, ZF, AF, CF и PF. #### Примечания Как видно, нельзя сложить две ячейки памяти. Когда вторым операндом является явно заданное число, его знак расширяется до размера первого операнда. ### CALL `call
` сохраняет информацию (регистр `rip`) о текущем процессе и передает управление процессу, расположенному по адресу `
` (заменят значение регистра `rip` на `address`). #### Комбинации операндов В зависимости от типа адресации, `
` может быть как регистром или ячейкой памяти (абсолютная адресация), так и меткой (относительная адресация). #### Флаги Не меняются. #### Примечания При использовании в качестве абсолютного адреса значения вершины стека `[rsp]` (с использованием косвенной адресации), команда сначала сохранит необходимый адрес перехода, и только потом сохранит адрес возврата в стек. ### CMP `cmp , ` выполняет операцию вычитания (`sub , `) без сохранения результата. #### Комбинации операндов Те же, что и у [[#SUB|инструкции]] `sub`. #### Флаги Ставит CF, OF, SF, ZF, AF и PF. #### Примечания В основном используется перед командами, исполнение которых зависит от флагов состояния. При необходимости, знак второго операнда расширяется до размера первого. ### DEC `dec ` уменьшает значение операнда на единицу. #### Комбинации операндов Регистр или ячейка памяти. #### Флаги Не меняет CF. Ставит OF, SF, ZF, AF и PF. #### Примечания Может использоваться для изменения счетчика цикла без изменения флага CF. Для того, чтобы также изменить значение флага CF, можно использовать [[#SUB|инструкцию]] `sub`. ### DIV `div ` производит беззнаковое деление значения регистра `ax` (или `dx:ax`, `edx:eax`, `rdx:rax`, в зависимости от размера) на операнд ``, сохраняя целую часть деления в регистр `al` (или `ax`, `eax`, `rax`), а остаток - в регистр `ah` (или `dx`, `edx`, `rdx`). #### Комбинации операндов Регистр или ячейка памяти. В зависимости от размера операнда, меняются регистры для изначального значения и результата. - ` = byte` (1 байт) - `ax -> al:ah` - ` = word` (2 байта) - `dx:ax -> dx:ax` - ` = dword` (4 байта) - `edx:eax -> edx:eax` - ` = qword` (8 байт) - `rdx:rax -> rdx:rax` #### Флаги Не определены CF, OF, SF, ZF, AF и PF. #### Примечания Все значения округляются в сторону нуля. Чтобы не запутаться, в какой регистр какая часть результата записывается, можно регистры `rdx:rax` читать как дробь, где сверху будет `rdx` - остаток, а снизу - `rax` - целая часть. ### ENTER `enter , ` создает фрейм стека для подпрограммы с указанным размером `` и уровнем вложенности ``. При нулевом уровне вложенности сохраняет `rbp` в стеке, новое значение `rbp` ставит равным текущему `rsp`, а после сдвигает `rsp` на указанное количество байт ``. Если же вложенность больше 0, то помимо `rbp`, на стек будут также записаны значения, указывающие на фреймы всех предыдущих уровней вложенности, а также указатель текущего фрейма, и только после этого выделится нужное количество памяти. #### Комбинации операндов `` - явно заданное 16-битное число `` - явно заданное 8-битное число #### Флаги Не меняет. #### Примечания Уровни вложенности применяются только в блочных структурах, где нужен доступ к памяти функции предыдущих уровней вложенности. На практике же можно применять только нулевой уровень вложенности. В таком случае команду `enter , 0` можно расписать как `push rbp; mov rbp, rsp; sub rsp, `. Чаще всего используется в паре с [[#LEAVE|инструкцией]] `leave`. ### IDIV `idiv ` производит знаковое деление значения регистра `ax` (или `dx:ax`, `edx:eax`, `rdx:rax`, в зависимости от размера) на операнд ``, сохраняя целую часть деления в регистр `al` (или `ax`, `eax`, `rax`), а остаток - в регистр `ah` (или `dx`, `edx`, `rdx`). #### Примечания В основном, данная команда схожа с [[#DIV|инструкцией]] `div`, только используется для знаковых чисел, а не для беззнаковых. ### IMUL `imul , , ` производит знаковое умножение двух операндов. При этом операнды `` и `` необязательны, но от их наличия изменяется поведение команды. #### Комбинации операндов - При наличии только одного операнда `` команда аналогична [[#MUL|инструкции]] `mul`. В данном случае `` это регистр или ячейка памяти. - Если операнда два - `` и ``, тогда производится умножение значения операнда `` на значение операнда ``, а результат обрезается и записывается как значение операнда ``. В данном случае `` - регистр, а `` - регистр или ячейка памяти. - Если операнда три - ``, `` и ``, тогда производится умножение значения операнда `` на значение операнда ``, а результат обрезается и записывается как значение операнда ``. В данном случае `` - регистр, `` - регистр или ячейка памяти, а `` - явно заданное 8/16/32/64-битное число. #### Флаги Ставит CF и OF, если - для одного операнда: верхняя половина не ноль; - для двух или трех операндов: результат должен быть обрезан, чтобы поместится в ячейку; иначе CF и OF устанавливаются в ноль. Не определены SF, ZF, AF и PF. ### INC `inc ` увеличивает значение операнда `` на единицу. #### Комбинации операндов Регистр или ячейка памяти. #### Флаги Ставит OF, SF, ZF, AF и PF. Не меняет CF. #### Примечания Может использоваться для изменения счетчика цикла без изменения флага CF. Для того, чтобы также изменить значение флага CF, можно использовать [[#ADD|инструкцию]] `add`. ### JMP `jmp
` производит безусловный переход на другую часть программы, указанную адресом `
`, и передает ей управление программой. Помимо этого также существуют условные переходы, работающие по похожему принципу. Они производят переход только в определенном случае, в зависимости от значений установленных флагов. #### Условные переходы - `jc` - `jump if carry set (CF = 1)` - `jnc` - `jump if carry clear (CF = 0)` - `jo` - `jump if overflow set (OF = 1)` - `jno` - `jump if overflow clear (OF = 0)` - `jp` - `jump if parity set (PF = 1)` - `jnp` - `jump if parity clear (PF = 0)` - `js` - `jump if sign set (SF = 1)` - `jns` - `jump if sign clear (SF = 0)` - `jz` - `jump if zero set (ZF = 1)` - `jnz` - `jump if zero clear (ZF = 0)` - `je` - `jump if equal (ZF = 1)` - `jne` - `jump if not equal (ZF = 0)` - `ja` - `jump if above (CF = 0 & ZF = 0)` - `jna` - `jump if not above (CF = 1 & ZF = 1)` - `jae` - `jump if above or equal (CF = 0)` - `jnae` - `jump if not above or equal (CF = 1)` - `jb` - `jump if below (CF = 1)` - `jnb` - `jump if not below (CF = 0)` - `jbe` - `jump if below or equal (CF = 1 & ZF = 1)` - `jnbe` - `jump if not below or equal (CF = 0 & ZF = 0)` - `jg` - `jump if greater (ZF = 0 & SF = OF)` - `jng` - `jump if not greater (ZF = 1 & SF != OF)` - `jge` - `jump if greater or equal (SF = OF)` - `jnge` - `jump if not greater or equal (SF != OF)` - `jl` - `jump if less (SF != OF)` - `jnl` - `jump if not less (SF = OF)` - `jle` - `jump if less or equal (ZF = 1 & SF != OF)` - `jnle` - `jump if not less or equal (ZF = 0 & SF = OF)` #### Комбинации операндов Регистр, ячейка памяти или явно заданное число. #### Флаги Не меняет. #### Примечания Не сохраняет информацию о возврате. ### LEA `lea ,
` сохраняет адрес до значения по адресу `
` в качестве значения операнда ``. В зависимости от размера операндов, действие команды слегка меняется. Если они одного размера, ничего необычного не происходит. Если размер регистра превышает размер адреса, то адрес расширяется нулями до нужного значения и записывается в регистр. Если размер адреса больше размера регистра, то в регистр записывается только нижняя часть адреса. #### Комбинации операндов `` - регистр. `
` - ячейка памяти. #### Флаги Не меняет. ### LEAVE `leave` очищает стек от фрейма, который ранее был выделен с помощью [[#ENTER|инструкции]] `enter`. #### Флаги Не меняет. #### Примечания Данную команду можно заменить последовательностью команд `mov rsp, rbp; pop rbp`. Чаще всего эта команда сопровождается [[#RET|инструкцией]] `ret`, что возвращает управление предыдущей программе. ### MOV `mov , ` копирует значение операнда `` и записывает его как значение операнда ``. #### Комбинации операндов `` - `` - регистр или ячейка памяти - регистр - регистр - регистр или ячейка памяти - регистр или ячейка памяти - явно заданное значение #### Флаги Не меняет. #### Примечания Оба операнда должны быть одинакового размера. Как видно, оба операнда не могут быть ячейкой памяти. ### MUL `mul ` производит беззнаковое умножение значения операнда `` со значением регистра `al` (или `ax`, `eax`, `rax`, в зависимости от размера операнда ``) и записывает результат в регистр `ax` (или `dx:ax`, `edx:eax`, `rdx:rax`). #### Комбинации операндов Регистр или ячейка памяти. В зависимости от размера операнда, меняются регистры для изначального значения и результата. - ` = byte` (1 байт) - `al -> ax` - ` = word` (2 байта) - `ax -> dx:ax` - ` = dword` (4 байта) - `eax -> edx:eax` - ` = qword` (8 байт) - `rax -> rdx:rax` #### Флаги Ставит CF и OF в ноль, если верхняя половина результата пуста и равна нулю, иначе CF и OF ставятся в 1. Не определены SF, ZF, AF и PF. #### Примечания При записи результата два регистра можно рассматривать как соединенные вместе: меньшая часть записывается в регистр `rax`, а большая, если не вмещается, в регистр `rdx`. ### NEG `neg ` заменяет значение операнда на значение, полученное вычитанием изначального значения из нуля. #### Комбинации операндов Регистр или ячейка памяти. #### Флаги Ставит CF в 0, если значение операнда ` = 0`, иначе ставит CF в 1. Ставит OF, SF, ZF, AF и PF. ### POP `pop ` загружает значение, находящееся на вершине стека, в указанный операнд `` и увеличивает указатель вершины стека. В зависимости от размера читаемого операнда `` изменится и увеличение стека (сколько загружено, на столько стек и увеличится). #### Комбинации операндов Регистр или ячейка памяти. #### Флаги Не меняет. #### Примечания При исполнении команды `pop rsp` увеличивает указатель стека до того, как значение старой вершины стека будет записано в регистр. ### PUSH `push ` уменьшает указатель вершины стека и загружает значение операнда `` на вершину стека. В зависимости от размера операнда `` изменится и уменьшение стека (сколько будет загружено, на столько стек и уменьшится). #### Комбинации операндов Регистр, ячейка памяти или явно заданное значение. #### Флаги Не меняет. #### Примечания Если операнд - явно заданное число, занимающее меньше места, чем полное значение операнда, то недостающие биты будут заполнены в соответствии со знаком числа. Команда `push rsp` запишет значение регистра `rsp` такое, какое было до его уменьшения. То же самое происходит, если адрес операнда `` вычисляется на ходу и зависит от значения регистра `rsp`. ### RET `ret ` берет с вершины стека значение адреса и передает ему управление программой, уменьшая указатель стека на размер взятого адреса. Опционально может быть указан операнд ``, по значению которого будет освобождено соответствующее количество байт из стека (то есть указатель стека увеличится на соответствующее количество байт). #### Флаги Не меняет. #### Примечания Чаще всего используется после [[#CALL|инструкции]] `call` для возврата из подпрограммы. ### SAL/SAR/SHL/SHR `shift , ` (где `shift` - семейство команд сдвигов) сдвигает биты значения операнда `` на соответствующее значение операнда ``. Существует несколько разновидностей сдвигов: - `sal` - арифметический сдвиг влево; - `sar` - арифметический сдвиг вправо; - `shl` - логический сдвиг влево; - `shr` - логический сдвиг вправо. Арифметический и логический сдвиг влево производят одну и ту же операцию: сдвигают биты значения влево (в сторону наиболее значимых битов). Логический сдвиг вправо заменяет все освобожденные сдвигом биты на ноль. Арифметический сдвиг вправо устанавливает все освобожденные сдвигом биты в зависимости от знака изначального числа. #### Комбинации операндов `` - регистр или ячейка памяти. `` - явно заданное 8-битное значение или значение регистра `cl`. При этом данное значение урезается до 6 бит. #### Флаги Если значение операнда ` = 0`, не меняет. Ставит CF по последнему сдвинутому за пределы числа биту; CF не определен для логических сдвигов, если значение операнда `` больше или равно битовой длине значения операнда ``. Ставит OF в 0 только для сдвигов на один бит только в том случае, если - при сдвиге влево два крайних левых бита равны; - при арифметическом сдвиге вправо; иначе ставит в 1. В случае логических сдвигов вправо ставит OF по значению старшего бита изначального числа. Иначе, OF не определен. Ставит SF, ZF и PF. Не определен AF. #### Примечания Сдвиги также можно представить как умножение на два `` количество раз (в случае сдвига влево) или как деление на два `` количество раз (знаковое (с округлением в сторону отрицательной бесконечности) или беззнаковое, в зависимости от соответственно арифметического или логического сдвига вправо). ### SUB `sub , ` вычитает значение операнда `` из операнда ``, и записывает результат в операнд ``. #### Комбинации операндов `` - `` - регистр - регистр или ячейка памяти - регистр или ячейка памяти - регистр - регистр - явно заданный операнд - `al/ax/eax/rax` - явно заданный операнд #### Флаги Ставит OF, SF, ZF, AF, PF и CF. #### Примечания Оба операнда не могут быть одновременно ячейками памяти. Когда используется явно заданное значение, его знак расширяется до размера операнда ``. ### SYSCALL `syscall` вызывает системный вызов на основе переданных через аргументы функции значений. #### Флаги Ставит все флаги. #### Примечания Подробнее об этой команде можно почитать в конспекте [семинара 1](Среда%20выполнения.%20Основы%20языка%20ассемблера.md#Команды). ### TEST `test , ` выполняет операцию логического "или" между значениями операндов `` и `` без сохранения результата. #### Комбинации операндов `` - `` - регистр или ячейка памяти - регистр - регистр или ячейка памяти - явно заданное число - `al/ax/eax/rax` - явно заданное число #### Флаги Ставит OF и CF в 0. Ставит SF, ZF и PF. Не определен AF. #### Примечания Часто эту команду используют для сравнения операнда с нулем, дублируя этот операнд. ### XOR `xor , ` выполняет операцию исключающего "или" между значениями операндов `` и `` и записывает значение результата как значение операнда ``. #### Комбинации операндов `` - `` - регистр - регистр или ячейка памяти - регистр или ячейка памяти - регистр - регистр - явно заданный операнд - `al/ax/eax/rax` - явно заданный операнд #### Флаги Ставит AF и CF в 0. Ставит SF, ZF и PF. Не определен AF. #### Примечания Оба операнда не могут одновременно быть ячейками памяти. Часто данную команду используют для обнуления указанного дважды регистра.