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

Содержание

Слайд 2

Безусловный переход Безусловный переход осуществляется либо к метке, заданной в явном

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

Безусловный переход осуществляется либо к метке, заданной в явном виде,

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

NEXT: MOV EAX, a

Слайд 3

Условный переход Условный переход осуществляется только к метке, заданной в явном

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

Условный переход осуществляется только к метке, заданной в явном виде.

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

Условный переход Переходы по обнулению счётчика и по состоянию основных флагов:

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

Переходы по обнулению счётчика и по состоянию основных флагов:

Слайд 5

Условный переход Переходы по результату команды сравнения (комбинация флагов): E (Equal)

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

Переходы по результату команды сравнения (комбинация флагов):
E (Equal) — равенство;
A

(Above), B (Below) — больше/меньше (беззнаковые);
G (Greater), L (Less) — больше/меньше (знаковые).
Слайд 6

Условный переход Пример: MOV EAX, a ADD EAX, b CMP EAX,

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

Пример:
<…>
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 или её варианты.

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

Команды организации циклов Цикл с проверкой ECX > 0: LOOP label

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

Цикл с проверкой ECX > 0:
LOOP label
Цикл с проверкой

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

Команды организации циклов Пример: MOV ECX, n LEA EBX, arr XOR

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

Пример:
<…>
MOV ECX, n
LEA EBX, arr
XOR

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

Команды организации циклов Организация вложенного цикла: в качестве индекса используем регистр

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

Организация вложенного цикла:
в качестве индекса используем регистр EDI;

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

Команды вызова/возврата из процедуры Вызов процедуры осуществляется с помощью команды CALL

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

Вызов процедуры осуществляется с помощью команды
CALL proc_name
Процедура может

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

Структура процедуры proc_name PROC PUSH EBP MOV EBP, ESP ADD EBP,

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

proc_name PROC
PUSH EBP
MOV EBP, ESP
ADD EBP, 8 ; в EBP —

адрес верхнего параметра

POP EBP
RET
proc_name ENDP
Слайд 13

Вызов процедуры из ASM-кода PUSH par1 PUSH par2 … PUSH parN

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

<…>
PUSH par1
PUSH par2

PUSH parN
CALL proc_name
<…>
--------------------------------------------------
proc_name PROC
PUSH EBP
MOV EBP,

ESP
ADD EBP, 8
<…>
POP EBP
RET
proc_name ENDP

par1

par2


parN

EIP

EBP

ESP

EBP

Стек

Слайд 14

Вызов ASM-процедуры из C Для вызова ассемблерной процедуры из кода на

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

Для вызова ассемблерной процедуры из кода на языке

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