====== Введение в Ассемблер. Команды передачи управления. Условный и безусловный переход. Организация циклов ======
===== Команды передачи управления =====
Среди команд передачи управления можно выделить **команды условного и безусловного перехода**. Кроме того, к таким командам относятся:
* команда вызова процедуры (CALL);
* команда возврата из процедуры (RET);
* команда вызова прерывания (INT);
* команда возврата из прерывания (IRET).
Мы будем ориентироваться в написании программ на Windows. Каждая задача в операционной системе Windows работает в своем виртуальном адресном пространстве, представляющем по сути один большой сегмент, размер которого определяется 32-битным числом (для 32-битной Windows). Поэтому все переходы в программах для Windows осуществляются в рамках этого сегмента и предполагают простое изменение содержимого регистра EIP (указателя команд). Отметим, что в некоторых случаях (в других ОС) приходится осуществлять межсегментную передачу управления.
===== Заголовок =====
// иллюстрация использования меток Си и ассемблера одновременно
#include
#include
#include
DWORD a,b,c;
void main()
{
a = 400;
b = 600;
c = 700;
__asm{
MOV EAX, a;
MOV EBX, b;
JMP L2;
L1:
MOV EDX, EAX;
L2:
ADD EBX, EAX;
MOV c, EBX;
JMP L3;
MOV c, EAX;
};
L3:
printf("%d\n", c);
c+=100;
L4: if(c>2000)
_getch();
else goto L3;
// обращаться из Си к ассемблерным меткам нельзя. Следующий код не работает:
// goto L1;
};
===== Пример. Нахождение максимального из трех чисел =====
// нахождение максимального из 3 целых чисел
#include
#include
#include
DWORD a,b,c,d;
void main()
{
a = 400;
b = 600;
c = 700;
__asm{
MOV EAX, a;
CMP EAX, b; // сравниваем содержимое регистра EAX и переменную b
JA L1; // ***если a>b, то максимальное из чисел a и b - это a, оно хранится в буфере EAX
// если EAX>b то переходим по метке L1 (JA - для беззнаковых целых,
// JG - для чисел со знаком. Можно использовать JZ - (если нуль) или
// JE (если равно). При помощи этих команд результат выполнения последней арифметической
// команды сравнивается с нулем)
MOV EAX, b; // *** иначе максимальное из чисел a и b - это b, помещаем его в буфер EAX
L1:
CMP EAX, c; // сравниваем содержимое регистра EAX (максимальное из чисел a и b) и переменную c
JNA L2; // если EAX меньше с, то перейти по метке L2
JMP L3; // безусловный переход по метке L3, если больше или равно
// JMP l1 - переход по адресу, который содержится в переменной l1
// JMP EAX - переход по адресу, который содержится в регистре EAX
// JMP [EAX] - переход по адресу, который находится в переменной,
// адрес которой находится в регистре EAX
L2:
MOV EAX, c; // максимальное из 3 чисел - с
L3:
MOV d, EAX; // выводим максимальное из 3 чисел
};
printf("%d", d);
_getch();
};
{{workroom:inb31-2013:comp:index:lab10:lab10_1a.png}}
\
Назад: [[workroom:inb31-2013:comp:index:lab10]]
{{tag>}}