Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
А С Е М Б Л Е Р.doc
Скачиваний:
7
Добавлен:
12.08.2019
Размер:
835.58 Кб
Скачать

Команди переходу після зіставлення чисел з урахуванням знака:

Команда

Розшифровка

Умова переходу

Прапори

Синоніми

Антонім

JG

Jump if greater

А > B

SF=OF | ZF=0

JNLE

JNG

JNLE

Jump if not lower or equal

А не <= B

SF=OF | ZF=0

JG

JLE

JGE

Jump if greater or equal

А >= B

SF =

JNL

JNGE

JNL

Jump if not lower

А не < B

SF =

JGE

JL

JL

Jump if lower

А < B

SF !=

JNGE

JNL

JNGE

Jump if not greater or equal

А не >= B

SF !=

JL

JGE

JLE

Jump if lower or equal

А <= B

CF!=OF | ZF=1

JNG

JNLE

JNG

Jump if not greater

А не > B

CF!=OF | ZF=1

JLE

JG

JE

Jump if equal

А = B

ZF = 1

JZ

JNE

JNE

Jump if not equal

А не = B

ZF = 0

JNZ

JE

В таблицях знак «|» означає «або», а «!» - «не».

Приклади роботи з умовними переходами:

CMP АХ, 4 ; Порівнюємо вміст АХ і 4

JB exit ; Якщо АХ менше 4, то переходимо по мітці

SUB BX, 10 ; віднімаємо 10 з BX

JZ lb1 ; якщо в результаті вийшов 0, то йдемо на lb1

JG lb2 ; якщо результат позитивний, то йдемо на lb2

Але необхідно враховувати, що мітка повинна знаходитися не далі 127 байтів від інструкції умовного переходу (в трансльованому коді) для 8086 або 32767 байтів для 80386. Якщо все ж таки ця ситуація відбулася, її можна вирішити за допомогою введення додаткової мітки. Наприклад, для мітки exit з попереднього фрагмента:

CMP АХ, 4 ; Порівнюємо вміст АХ і 4

JNB dop ; Замінюємо команду антонімом. Тепер, у випадку

; АХ >= 4, переходимо на додаткову мітку

JMP exit ; Якщо ж АХ менше 4, то переходимо на exit

dop: SUB BX, 10 ; віднімаємо 10 з BX

JZ lb1 ; якщо в результаті вийшов 0, то йдемо на lb1

JG lb2 ; якщо результат позитивний, то йдемо на lb2

За допомогою безумовних переходів в асемблерних програмах можна організовувати нескінченні цикли:

forever: ; мітка початку циклу

...

JMP forever ; перехід на початок

Очевидної користі в нескінченному циклі немає, набагато частіше використовують цикли з перевіркою умови виходу. Наприклад, цикл з послеусловием:

MOV АХ, 100 ; АХ використовуватиметься як лічильник повторів

beg: ; мітка початку циклу

...

DEC АХ ; віднімаємо від АХ одиницю

JNZ beg ; якщо АХ не нуль, то перехід на початок

Той же цикл, тільки з предусловием:

MOV АХ, 100 ; АХ використовуватиметься як лічильник повторів

beg: DEC АХ ; віднімаємо від АХ одиницю

JZ ex ; якщо АХ нуль, то перехід на кінець циклу

...

JMP beg ; безумовний перехід на початок

ex:

Як і в наведеному приклад, часто з'являється необхідність повторити цикл певна кількість раз. Для спрощення цієї процедури, в процесорі 8086 існує інструкція LOOP. Її синтаксис аналогічний команді умовного переходу.

LOOP <метка або відносний адрес>

Команда LOOP виконує дві операції: вона віднімає з регістра CX одиницю, і якщо після цього CX не рівний нулю, то переходить на вказану мітку. Тобто, ця команду можна вигідно застосувати для циклу з послеусловием з прикладу, тільки тепер як регістр-лічильника виступатиме CX:

MOV CX, 100 ; лічильник повторів

beg: ; мітка початку циклу

...

LOOP beg ; CX = CX-1. Якщо CX не нуль, то перехід на beg

Цикли можна широко використовувати для роботи з масивами даних. Наприклад, підрахуємо суму всіх елементів масиву:

DATA SEGMENT

А DW 1, 3, 6, 3, 7, 1, 0, 42, 3, 87 ; масив

DATA ENDS

CODE SEGMENT

...

MOV АХ, 0 ; АХ берегтиме суму

MOV CX, 10 ; лічильник повторів

MOV SI, offset А ; в SI покладемо зсув А щодо сегменту даних

beg: ADD АХ [SI] ; додамо до суми вміст пам'яті за адресою DS:SI

ADD SI, 2 ; перейдемо на наступний елемент масиву

LOOP beg ; CX = CX-1. Якщо CX не нуль, то перехід на beg

...

CODE ENDS

В процесорі 80386 програма ще більш спрощується, тільки тепер сума вважається з кінця масиву:

.386

DATA SEGMENT USE16

А DW 1, 3, 6, 3, 7, 1, 0, 42, 3, 87 ; масив

DATA ENDS

CODE SEGMENT USE16

...

MOV EAX, 0 ; EAX берегтиме суму

MOV ЕСX, 10 ; лічильник повторів

beg: ADD АХ, А[ECX*2-2] ; кожний елемент масиву займає 2 байти

LOOP beg ; ЕСX = ECX-1. Якщо ЕСX не нуль, то перехід на beg

...

CODE ENDS

В деяких версіях для обробки подібних програм слід використовувати команду TLINK/3.

Завдання на лабораторну роботу

Написати програму для процесора 80386, яка копіює рядок символів, що лежить в одному з сегментів, в масив двобайтових слів за певною адресою. В старші байти масиву слів записати номер свого варіанту. Відстежити роботу програми у відладчику.

Приклад виконання роботи

В наведеному приклад виконується копіювання трьох рядків. Перший рядок лежить в сегменті даних, друга – в сегменті стека, а третя – в сегменті коду після безумовного переходу. Використовуються цикли з послеусловием. Рядки копіюються за адресами 0b800h, 0b800h:160, 0b800h:320 відповідно.

.386

ASSUME CS:CODE, DS:DATA ; зв'язуємо сегментні регістри і сегменти

;-----------------------------------------------------------------------------

DATA SEGMENT USE16 сегмент даних

str1 DB 'Строка 1 '

DATA ENDS

;-----------------------------------------------------------------------------

STK SEGMENT USE16 STACK ; сегмент стека

str2 DB 'Строка 2 '

DB 100 dup (0) ; буфер для системного стека

STK ENDS

;-----------------------------------------------------------------------------

CODE SEGMENT USE16

start: MOV ах, 0B800h ; вкажемо в ES сегмент для висновку

MOV es, ах

MOV ах, DATA ; в DS - сегмент даних

MOV ds, ах

MOV ebx, 0 ; лічильник циклу

LEA edi, str1 ; ефективна адреса рядка

MOV ah, 13 ; старший байт записуваних слів

c1: MOV al [ebx + edi] ; символ з рядка -> AL

MOV es:[ebx*2], ах ; АХ -> сегмент висновку

INC ebx

CMP ebx, 9 ; послеусловие

JB c1

MOV ebx, 0 ; лічильник циклу

LEA edi, str2

MOV ah, 14

c2: MOV al, ss:[ebx + edi] ; символ з рядка -> AL

MOV es:[160 + ebx*2], ах ; АХ -> сегмент висновку

INC ebx

CMP ebx, 9 ; послеусловие

JB c2

MOV ebx, 0 ; лічильник циклу

LEA edi, str3 ; ефективна адреса рядка

MOV AH, 15 ; старший байт записуваних слів

c3: MOV al, cs:[ebx + edi] ; символ з рядка -> AL

MOV es:[320 + ebx*2], ах ; АХ -> сегмент висновку

INC ebx

CMP ebx, 8 ; послеусловие

JB c3

JMP over

str3 DB 'Строка 3'

over: MOV ah, 1 ; запит символу з клавіатури – використовується в

INT 21h ; якості затримки для перевірки висновку на екран

MOV ах, 4c00h ; вихід в Ос

INT 21h

CODE ENDS

END start ; start – точка входу в програму