Files
Info/2 курс/Языки программирования/Библиотека команд ассемблера.md
T

24 KiB
Raw Blame History

Содержание

  • #ADD
  • #CALL
  • #CMP
  • #DEC
  • #DIV
  • #ENTER
  • #IDIV
  • #IMUL
  • #INC
  • #JMP
  • #LEA
  • #LEAVE
  • #MOV
  • #MUL
  • #NEG
  • #POP
  • #PUSH
  • #RET
  • #SAL/SAR/SHL/SHR
  • #SUB
  • #SYSCALL
  • #TEST
  • #XOR

ADD

add <op1>, <op2> добавляет значение операнда <op1> к значению операнда <op2> и записывает результат в операнд <op1>.

Комбинации операндов

<op1> - <op2>

  • регистр - регистр или ячейка памяти
  • регистр или ячейка памяти - регистр
  • регистр - явно заданный операнд
  • al/ax/eax/rax - явно заданный операнд

Флаги

Ставит OF, SF, ZF, AF, CF и PF.

Примечания

Как видно, нельзя сложить две ячейки памяти. Когда вторым операндом является явно заданное число, его знак расширяется до размера первого операнда.

CALL

call <address> сохраняет информацию (регистр rip) о текущем процессе и передает управление процессу, расположенному по адресу <address> (заменят значение регистра rip на address).

Комбинации операндов

В зависимости от типа адресации, <address> может быть как регистром или ячейкой памяти (абсолютная адресация), так и меткой (относительная адресация).

Флаги

Не меняются.

Примечания

При использовании в качестве абсолютного адреса значения вершины стека [rsp] (с использованием косвенной адресации), команда сначала сохранит необходимый адрес перехода, и только потом сохранит адрес возврата в стек.

CMP

cmp <op1>, <op2> выполняет операцию вычитания (sub <op1>, <op2>) без сохранения результата.

Комбинации операндов

Те же, что и у #SUB sub.

Флаги

Ставит CF, OF, SF, ZF, AF и PF.

Примечания

В основном используется перед командами, исполнение которых зависит от флагов состояния. При необходимости, знак второго операнда расширяется до размера первого.

DEC

dec <op> уменьшает значение операнда на единицу.

Комбинации операндов

Регистр или ячейка памяти.

Флаги

Не меняет CF. Ставит OF, SF, ZF, AF и PF.

Примечания

Может использоваться для изменения счетчика цикла без изменения флага CF. Для того, чтобы также изменить значение флага CF, можно использовать #SUB sub.

DIV

div <op> производит беззнаковое деление значения регистра ax (или dx:ax, edx:eax, rdx:rax, в зависимости от размера) на операнд <op>, сохраняя целую часть деления в регистр al (или ax, eax, rax), а остаток - в регистр ah (или dx, edx, rdx).

Комбинации операндов

Регистр или ячейка памяти. В зависимости от размера операнда, меняются регистры для изначального значения и результата.

  • <op> = byte (1 байт) - ax -> al:ah
  • <op> = word (2 байта) - dx:ax -> dx:ax
  • <op> = dword (4 байта) - edx:eax -> edx:eax
  • <op> = qword (8 байт) - rdx:rax -> rdx:rax

Флаги

Не определены CF, OF, SF, ZF, AF и PF.

Примечания

Все значения округляются в сторону нуля. Чтобы не запутаться, в какой регистр какая часть результата записывается, можно регистры rdx:rax читать как дробь, где сверху будет rdx - остаток, а снизу - rax - целая часть.

ENTER

enter <op1>, <op2> создает фрейм стека для подпрограммы с указанным размером <op1> и уровнем вложенности <op2>. При нулевом уровне вложенности сохраняет rbp в стеке, новое значение rbp ставит равным текущему rsp, а после сдвигает rsp на указанное количество байт <op1>. Если же вложенность больше 0, то помимо rbp, на стек будут также записаны значения, указывающие на фреймы всех предыдущих уровней вложенности, а также указатель текущего фрейма, и только после этого выделится нужное количество памяти.

Комбинации операндов

<op1> - явно заданное 16-битное число <op2> - явно заданное 8-битное число

Флаги

Не меняет.

Примечания

Уровни вложенности применяются только в блочных структурах, где нужен доступ к памяти функции предыдущих уровней вложенности. На практике же можно применять только нулевой уровень вложенности. В таком случае команду enter <op1>, 0 можно расписать как push rbp; mov rbp, rsp; sub rsp, <op1>. Чаще всего используется в паре с #LEAVE leave.

IDIV

idiv <op> производит знаковое деление значения регистра ax (или dx:ax, edx:eax, rdx:rax, в зависимости от размера) на операнд <op>, сохраняя целую часть деления в регистр al (или ax, eax, rax), а остаток - в регистр ah (или dx, edx, rdx).

Примечания

В основном, данная команда схожа с #DIV div, только используется для знаковых чисел, а не для беззнаковых.

IMUL

imul <op1>, <op2>, <op3> производит знаковое умножение двух операндов. При этом операнды <op2> и <op3> необязательны, но от их наличия изменяется поведение команды.

Комбинации операндов

  • При наличии только одного операнда <op1> команда аналогична #MUL mul. В данном случае <op1> это регистр или ячейка памяти.
  • Если операнда два - <op1> и <op2>, тогда производится умножение значения операнда <op1> на значение операнда <op2>, а результат обрезается и записывается как значение операнда <op1>. В данном случае <op1> - регистр, а <op2> - регистр или ячейка памяти.
  • Если операнда три - <op1>, <op2> и <op3>, тогда производится умножение значения операнда <op2> на значение операнда <op3>, а результат обрезается и записывается как значение операнда <op1>. В данном случае <op1> - регистр, <op2> - регистр или ячейка памяти, а <op3> - явно заданное 8/16/32/64-битное число.

Флаги

Ставит CF и OF, если

  • для одного операнда: верхняя половина не ноль;
  • для двух или трех операндов: результат должен быть обрезан, чтобы поместится в ячейку; иначе CF и OF устанавливаются в ноль. Не определены SF, ZF, AF и PF.

INC

inc <op> увеличивает значение операнда <op> на единицу.

Комбинации операндов

Регистр или ячейка памяти.

Флаги

Ставит OF, SF, ZF, AF и PF. Не меняет CF.

Примечания

Может использоваться для изменения счетчика цикла без изменения флага CF. Для того, чтобы также изменить значение флага CF, можно использовать #ADD add.

JMP

jmp <address> производит безусловный переход на другую часть программы, указанную адресом <address>, и передает ей управление программой. Помимо этого также существуют условные переходы, работающие по похожему принципу. Они производят переход только в определенном случае, в зависимости от значений установленных флагов.

Условные переходы

  • 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 <op>, <address> сохраняет адрес до значения по адресу <address> в качестве значения операнда <op>. В зависимости от размера операндов, действие команды слегка меняется. Если они одного размера, ничего необычного не происходит. Если размер регистра превышает размер адреса, то адрес расширяется нулями до нужного значения и записывается в регистр. Если размер адреса больше размера регистра, то в регистр записывается только нижняя часть адреса.

Комбинации операндов

<op> - регистр. <address> - ячейка памяти.

Флаги

Не меняет.

LEAVE

leave очищает стек от фрейма, который ранее был выделен с помощью #ENTER enter.

Флаги

Не меняет.

Примечания

Данную команду можно заменить последовательностью команд mov rsp, rbp; pop rbp. Чаще всего эта команда сопровождается #RET ret, что возвращает управление предыдущей программе.

MOV

mov <op1>, <op2> копирует значение операнда <op2> и записывает его как значение операнда <op1>.

Комбинации операндов

<op1> - <op2>

  • регистр или ячейка памяти - регистр
  • регистр - регистр или ячейка памяти
  • регистр или ячейка памяти - явно заданное значение

Флаги

Не меняет.

Примечания

Оба операнда должны быть одинакового размера. Как видно, оба операнда не могут быть ячейкой памяти.

MUL

mul <op> производит беззнаковое умножение значения операнда <op> со значением регистра al (или ax, eax, rax, в зависимости от размера операнда <op>) и записывает результат в регистр ax (или dx:ax, edx:eax, rdx:rax).

Комбинации операндов

Регистр или ячейка памяти. В зависимости от размера операнда, меняются регистры для изначального значения и результата.

  • <op> = byte (1 байт) - al -> ax
  • <op> = word (2 байта) - ax -> dx:ax
  • <op> = dword (4 байта) - eax -> edx:eax
  • <op> = qword (8 байт) - rax -> rdx:rax

Флаги

Ставит CF и OF в ноль, если верхняя половина результата пуста и равна нулю, иначе CF и OF ставятся в 1. Не определены SF, ZF, AF и PF.

Примечания

При записи результата два регистра можно рассматривать как соединенные вместе: меньшая часть записывается в регистр rax, а большая, если не вмещается, в регистр rdx.

NEG

neg <op> заменяет значение операнда на значение, полученное вычитанием изначального значения из нуля.

Комбинации операндов

Регистр или ячейка памяти.

Флаги

Ставит CF в 0, если значение операнда <op> = 0, иначе ставит CF в 1. Ставит OF, SF, ZF, AF и PF.

POP

pop <op> загружает значение, находящееся на вершине стека, в указанный операнд <op> и увеличивает указатель вершины стека. В зависимости от размера читаемого операнда <op> изменится и увеличение стека (сколько загружено, на столько стек и увеличится).

Комбинации операндов

Регистр или ячейка памяти.

Флаги

Не меняет.

Примечания

При исполнении команды pop rsp увеличивает указатель стека до того, как значение старой вершины стека будет записано в регистр.

PUSH

push <op> уменьшает указатель вершины стека и загружает значение операнда <op> на вершину стека. В зависимости от размера операнда <op> изменится и уменьшение стека (сколько будет загружено, на столько стек и уменьшится).

Комбинации операндов

Регистр, ячейка памяти или явно заданное значение.

Флаги

Не меняет.

Примечания

Если операнд - явно заданное число, занимающее меньше места, чем полное значение операнда, то недостающие биты будут заполнены в соответствии со знаком числа. Команда push rsp запишет значение регистра rsp такое, какое было до его уменьшения. То же самое происходит, если адрес операнда <op> вычисляется на ходу и зависит от значения регистра rsp.

RET

ret <op> берет с вершины стека значение адреса и передает ему управление программой, уменьшая указатель стека на размер взятого адреса. Опционально может быть указан операнд <op>, по значению которого будет освобождено соответствующее количество байт из стека (то есть указатель стека увеличится на соответствующее количество байт).

Флаги

Не меняет.

Примечания

Чаще всего используется после #CALL call для возврата из подпрограммы.

SAL/SAR/SHL/SHR

shift <op1>, <op2> (где shift - семейство команд сдвигов) сдвигает биты значения операнда <op1> на соответствующее значение операнда <op2>. Существует несколько разновидностей сдвигов:

  • sal - арифметический сдвиг влево;
  • sar - арифметический сдвиг вправо;
  • shl - логический сдвиг влево;
  • shr - логический сдвиг вправо. Арифметический и логический сдвиг влево производят одну и ту же операцию: сдвигают биты значения влево (в сторону наиболее значимых битов). Логический сдвиг вправо заменяет все освобожденные сдвигом биты на ноль. Арифметический сдвиг вправо устанавливает все освобожденные сдвигом биты в зависимости от знака изначального числа.

Комбинации операндов

<op1> - регистр или ячейка памяти. <op2> - явно заданное 8-битное значение или значение регистра cl. При этом данное значение урезается до 6 бит.

Флаги

Если значение операнда <op2> = 0, не меняет. Ставит CF по последнему сдвинутому за пределы числа биту; CF не определен для логических сдвигов, если значение операнда <op2> больше или равно битовой длине значения операнда <op1>. Ставит OF в 0 только для сдвигов на один бит только в том случае, если

  • при сдвиге влево два крайних левых бита равны;
  • при арифметическом сдвиге вправо; иначе ставит в 1. В случае логических сдвигов вправо ставит OF по значению старшего бита изначального числа. Иначе, OF не определен. Ставит SF, ZF и PF. Не определен AF.

Примечания

Сдвиги также можно представить как умножение на два <op2> количество раз (в случае сдвига влево) или как деление на два <op2> количество раз (знаковое (с округлением в сторону отрицательной бесконечности) или беззнаковое, в зависимости от соответственно арифметического или логического сдвига вправо).

SUB

sub <op1>, <op2> вычитает значение операнда <op2> из операнда <op1>, и записывает результат в операнд <op1>.

Комбинации операндов

<op1> - <op2>

  • регистр - регистр или ячейка памяти
  • регистр или ячейка памяти - регистр
  • регистр - явно заданный операнд
  • al/ax/eax/rax - явно заданный операнд

Флаги

Ставит OF, SF, ZF, AF, PF и CF.

Примечания

Оба операнда не могут быть одновременно ячейками памяти. Когда используется явно заданное значение, его знак расширяется до размера операнда <op1>.

SYSCALL

syscall вызывает системный вызов на основе переданных через аргументы функции значений.

Флаги

Ставит все флаги.

Примечания

Подробнее об этой команде можно почитать в конспекте семинара 1.

TEST

test <op1>, <op2> выполняет операцию логического "или" между значениями операндов <op1> и <op2> без сохранения результата.

Комбинации операндов

<op1> - <op2>

  • регистр или ячейка памяти - регистр
  • регистр или ячейка памяти - явно заданное число
  • al/ax/eax/rax - явно заданное число

Флаги

Ставит OF и CF в 0. Ставит SF, ZF и PF. Не определен AF.

Примечания

Часто эту команду используют для сравнения операнда с нулем, дублируя этот операнд.

XOR

xor <op1>, <op2> выполняет операцию исключающего "или" между значениями операндов <op1> и <op2> и записывает значение результата как значение операнда <op1>.

Комбинации операндов

<op1> - <op2>

  • регистр - регистр или ячейка памяти
  • регистр или ячейка памяти - регистр
  • регистр - явно заданный операнд
  • al/ax/eax/rax - явно заданный операнд

Флаги

Ставит AF и CF в 0. Ставит SF, ZF и PF. Не определен AF.

Примечания

Оба операнда не могут одновременно быть ячейками памяти. Часто данную команду используют для обнуления указанного дважды регистра.