Ассемблер Часть 2
Безусловный переход
Условный переход
Условный переход
Условный переход
Условный переход
Команды организации циклов
Команды организации циклов
Команды организации циклов
Команды организации циклов
Команды вызова/возврата из процедуры
Структура процедуры
Вызов процедуры из ASM-кода
Вызов ASM-процедуры из C
Вызов процедуры из кода на языке C
444.50K
Category: programmingprogramming

Ассемблер. Часть 2

1. Ассемблер Часть 2

Смирнов Александр Валерьевич
Кафедра теоретической информатики

2. Безусловный переход

Безусловный переход осуществляется либо к метке, заданной в
явном виде, либо по адресу команды, содержащемуся в
регистре или в оперативной памяти.
JMP addr
Пример:
JMP NEXT

NEXT: MOV EAX, a

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

Условный переход осуществляется только к метке, заданной в
явном виде. Условие определяется по состоянию флагов
(например, после применения команды CMP) или по состоянию
счётчика ECX.
Общий синтаксис оператора условного перехода (вместо <f>
подставляется нужная буквенная комбинация):
J<f> label

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

Переходы по обнулению счётчика и по состоянию основных
флагов:
Оператор
Условие
Оператор
Условие
JCXZ
ECX = 0
JZ
ZF = 1
(op1 = op2)
JNZ
ZF = 0
(op1 ≠ op2)
JC
CF = 1
JNC
CF = 0
JS
SF = 1
JNS
SF = 0
JO
OF = 1
JNO
OF = 0
JP
PF = 1
JNP
PF = 0

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

Переходы по результату команды сравнения (комбинация
флагов):
E (Equal) — равенство;
A (Above), B (Below) — больше/меньше (беззнаковые);
G (Greater), L (Less) — больше/меньше (знаковые).
Оператор
JE
Условие
op1 = op2
(аналогично JZ)
Оператор
JNE
Условие
op1 ≠ op2
(аналогично JNZ)
JB, JNAE
op1 < op2
JA, JNBE
op1 > op2
JBE, JNA
op1 ≤ op2
JAE, JNB
op1 ≥ op2
JL, JNGE
op1 < op2
JG, JNLE
op1 > op2
JLE, JNG
op1 ≤ op2
JGE, JNL
op1 ≥ op2

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

Пример:
<…>
MOV EAX, a
ADD EAX, b
CMP EAX, c
JLE NEXT
MOV EDX, c
MOV d, EDX
JMP NNEXT
NEXT: MOV d, EAX
NNEXT: <…>
В этом фрагменте процедуры d получит значение меньшего из
значений c и (a + b).

7. Команды организации циклов

При организации цикла используется команда LOOP или её
варианты. Общий синтаксис:
LOOP<f> label
Метка задаётся в явном виде. Регистр ECX используется в
качестве счётчика числа повторений цикла. Каждый раз при
выполнении команды LOOP<f> значение регистра ECX
уменьшается на 1, а затем сравнивается с 0.
Если ECX = 0, выполнение цикла заканчивается, и продолжает
выполняться код программы, записанный после команды
LOOP<f>.
Если ECX содержит ненулевое значение, то осуществляется
переход к метке.

8. Команды организации циклов

Цикл с проверкой ECX > 0:
LOOP label
Цикл с проверкой ECX > 0 && ZF = 1:
LOOPZ label
LOOPE label
Цикл с проверкой ECX > 0 && ZF = 0:
LOOPNZ label
LOOPNE label

9. Команды организации циклов

Пример:
CYC:
<…>
MOV ECX, n
LEA EBX, arr
XOR EAX, EAX
XOR ESI, ESI
ADD EAX, [EBX][ESI*4]
INC ESI
LOOP CYC
<…>
В цикле будет посчитана сумма элементов массива arr.

10. Команды организации циклов

Организация вложенного цикла:
• в качестве индекса используем регистр EDI;
• сохраняем
как быть сосчётчик
счётчиком
ECXECX?
в стеке.
Пример:
CYC1:
CYC2:
<…>
MOV ECX, n
MOV ESI, start_ind1
<…> ; внешний цикл
PUSH ECX
MOV ECX, m
MOV EDI, start_ind2
<…> ; внутренний цикл
LOOP CYC2
POP ECX
<…> ; продолжение внешнего цикла
LOOP CYC1
<…>

11. Команды вызова/возврата из процедуры

Вызов процедуры осуществляется с помощью команды
CALL proc_name
Процедура может быть задана меткой или адресом, указанном в
регистре или ячейке памяти.
Параметры, передаваемые в процедуру, необходимо сохранить
в стеке или регистрах. Команда CALL сохраняет в вершине
стека счётчик команд EIP (в плоской модели памяти).
Возврат из процедуры осуществляется по команде
RET
RET const
Здесь const соответствует количеству байт, занимаемому в стеке
параметрами процедуры, при возврате их нужно извлечь.
Команда RET восстанавливает указатель команд EIP из стека,
после чего удаляет из стека нужное число байт.

12. Структура процедуры

proc_name PROC
PUSH EBP
MOV EBP, ESP
ADD EBP, 8 ; в EBP — адрес верхнего параметра
<instructions>
POP EBP
RET <const>
proc_name ENDP

13. Вызов процедуры из ASM-кода

<…>
PUSH par1
PUSH par2

PUSH parN
CALL proc_name
<…>
-------------------------------------------------proc_name PROC
PUSH EBP
MOV EBP, ESP
ADD EBP, 8
EBP
EBP
EIP
parN

par2
<…>
POP EBP
RET <N*4>
proc_name ENDP
par1
Стек
ESP

14. Вызов ASM-процедуры из C

Для вызова ассемблерной процедуры из кода на языке C эту
процедуру нужно объявить как внешнюю:
extern "C"
{
<ret_type> <proc_name> (<params>);
}
Дальше вызов процедуры из кода C осуществляется обычным
образом.
Используется конвенция С:
Если процедура объявлена как функция (есть возвращаемое
значение), то это значение в ASM-коде должно быть записано
в регистр EAX (или в AL, AX, EDX:EAX).
Параметры процедуры сохраняются в стек справа налево
(первый параметр будет на вершине).
При этом в ассемблерном коде не нужно освобождать стек от
параметров при возврате — за это отвечает C.

15. Вызов процедуры из кода на языке C

extern "C"
{
int proc_name (<params>);
}
-------------------------------------------------<…>
a = proc_name(par1, …, parN);
<…>
-------------------------------------------------proc_name PROC
PUSH EBP
MOV EBP, ESP
ADD EBP, 8
<…>
MOV EAX, res
POP EBP
RET
proc_name ENDP
EBP
EBP
EIP
par1
par2

parN
Стек
ESP
English     Русский Rules