====== Введение в Ассемблер. Команды передачи управления. Условный и безусловный переход. Организация циклов ====== ===== Команды передачи управления ===== Среди команд передачи управления можно выделить **команды условного и безусловного перехода**. Кроме того, к таким командам относятся: * команда вызова процедуры (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>}}