Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГОС_ответы.doc
Скачиваний:
35
Добавлен:
27.10.2018
Размер:
21.59 Mб
Скачать

Idiv bx ;частное в ax, остаток в dx

30 Асемблер. Команди безумовної передачі керування. (прямі короткі; прямі; непрямі)

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

Команда JMP передает управление в указанную точку того же или другого программного сегмента. Адрес возврата не сохраняется. Команда JМР имеет пять разновидностей:

short - прямой короткий переход;

near ptr - прямой ближний переход;

far ptr - прямой дальний переход;

word ptr - косвенный ближний переход;

dword ptr - косвенный дальний переход.

Оператор Short

SHORT метка

Устанавливает тип метки SHORT (короткий). Если расстояние между меткой и переходом, ссылающимся на нее, меньше 128 байтов, метка может быть объявлена как метка типа SHORT. Команды, использующие метки SHORT, содержат в себе на 1 байт меньше, чем команды, использующие метки NEAR. Пример

jmp short shpoint ;Переход на метку shpoint в пределах +127...-128 байт

Прямой переход

В данном случае в качестве ор указывается метка той команды, на которую надо передать управление:

JMP <метка>

JMP L ; следующей будет выполняться команда с меткой L

L: MOV АХ,0

Косвенный переход

При косвенном переходе в команде перехода указывается не сам адрес перехода, а то место, где находится этот адрес. Таким местом может быть регистр общего назначения или слово памяти:

JMP г16 или JMP m16

В этих командах берется содержимое указанного регистра или слова памяти, оно рассматривается как адрес некоторой команды программы и именно по этому адресу делается переход. Причем этот адрес рассматривается как "настоящий", а не отсчитанный от команды перехода. Косвенные переходы используются в тех случаях, когда адрес перехода становится известным только во время счета программы.

31 Асемблер. Організація циклів за допомогою команд jcxz; loop, loopz та loopnz

В языке ассемблера есть команда условного перехода по значению регистра cx. Синтаксис этой команды такой

jcxz адрес_перехода ;jump if cx is zero

Организовать циклическое выполнение некоторых участков программы можно, применяя команды условного и безусловного перехода. Например, программа, вычисляющая сумму элементов массива, в этом случае будет содержать фрагменты:

len equ 5

a db 3,5,6,7,6

. . .

mov cx,len

xor ax,ax

xor si,si

. . .

cycl: jcxz exit

add ax,a[si]

inc si

dec cx

jmp cycl

exit: mov ax,4c00h

int 21h

Другой пример фрагмента программы, использующего команду условного перехода для организации цикла:

mov cx,len

. . .

metka:

тело цикла

dec cx

cmp cx,0

jne metka

С помощью команд перехода можно реализовать любые разветвления и циклы.

Команда LOOP

Пусть некоторую группу команд (тело цикла) надо повторить N раз (N>0). Тогда на языке ассемблера этот цикл можно реализовать по такой схеме:

MOV CX, N ;CX – счетчик цикла (число повторений)

L: ...

... ;тело цикла

DEC CX ;CX:=CX-1

СМР СХ,0 ;СХ=0?

JNE L ;СХ<>О -> goto L

Как видно, в конце таких циклов всегда применяется одна и та же тройка команд. Учитывая это, в систему команд ПК была введена специальная команда, которая объединяет в себе действия этих трех команд:

Управление циклом по счетчику: LOOP <метка>

Действие этой команды можно описать так:

CX:=CX-1; if CX<>O then goto <метка>

С помощью команды LOOP наш цикл запишется следующим образом:

MOV CX,N ;N>0

L: ... ;

... ; тело цикла

LOOP L

Как видно, получилось короче, да и работает команда LOOP быстрее этих трех команд. Поэтому, если можно, следует пользоваться командой LOOP.

Однако необходимо учитывать рад особенностей этой команды.

Во-первых, команда LOOP требует, чтобы в качестве счетчика цикла обязательно использовался регистр СХ, при другом регистре команду применять нельзя.

Во-вторых, начальное значение для СХ должно быть присвоено до цикла, причем этому регистру надо присваивать ровно столько, сколько раз должен повторяться цикл. Например, если цикл должен выполняться 100 раз, то в регистр СХ надо записывать именно 100, а не 99 или 101.

В-третьих, поскольку команда LOOP ставится в конце цикла, тело цикла хотя бы раз обязательно выполнится. Поэтому для случая СХ=0 наша схема цикла не подходит. Так вот, если возможен вариант, что число повторений может быть и нулевым, то при СХ=0 надо сделать обход цикла:

mov cx,n ; N>=0

JCXZ L1 ; СХ=0 L1

L: ... ;

... ; тело цикла

LOOP L

L1: ...

Именно ради осуществления таких обходов в ПК и была введена команда условного перехода JCXZ. В иных ситуациях она используется редко.

В-четвертых, как и команды условного перехода, команда LOOP реализует только короткий переход, поэтому расстояние от нее до начала цикла (метки L) не должно превышать 127-128 байтов (примерно 30-40 команд). Если цикл содержит больше команд, тогда команду LOOP использовать нельзя и надо реализовывать цикл по-иному.

Команды LOOPE/LOOPZ и LOOPNE/LOOPNZ

Эти команды похожи на команду LOOP, т. е. заставляют цикл повториться столько раз, сколько указано в регистре СХ, однако они допускают и досрочный выход из цикла.

Цикл по счетчику и пока равно (пока ноль): LOOPE <метка> или LOOPZ <метка>

(Названия LOOPE и LOOPZ являются синонимами.)

Действие этой команды можно описать так:

CX:=CX-1; If (CX<>O) and (ZF=1) then goto <метка>

Таким образом, эта команда совмещает в себе изменение счетчика цикла (регистра СХ) и условный переход, когда счетчик еще не нулевой и когда предыдущая команда выработала флаг нуля, равный 1. Причем этот переход – короткий.

Команда LOOPE используется для организации цикла с известным числом повторений, из которого возможен досрочный выход. До начала цикла в регистр СХ записывается число повторений. Сама команда LOOPE ставится в конец цикла (ее операнд – метка первой команды цикла), а перед ней помещается команда, меняющая флаг ZF (обычно это команда сравнения CMP). Команда LOOPE заставляет цикл повторяться СХ раз, но только если предыдущая команда фиксирует равенство сравниваемых величин (вырабатывает нулевой результат).

По какой именно причине произошел выход из цикла (по ZF=0 или СХ=0), надо проверять после цикла. Причем надо проверять флаг ZF (по команде JE/JZ или JNE/JNZ), а не регистр СХ, т. к. условие ZF=0 ("не равно") может появиться как раз на последнем шаге цикла, когда и регистр СХ стал нулевым.

Чаще всего команда LOOPE используется для поиска первого элемента некоторой последовательности, отличного от заданной величины.