Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция 6 / Лекция 6.doc
Скачиваний:
24
Добавлен:
10.06.2015
Размер:
226.3 Кб
Скачать

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

Предыдущее обсуждение выявило некоторые детали механизма перехода. Команды перехода модифицируют регистр указателя команды EIP/IP и, возможно, сегментный регистр кода CS. Что именно должно подвергнуться модификации, зависит:

от типа операнда в команде безусловного перехода (ближний или дальний);

от модификатора, который указывается перед адресом перехода в команде перехода и может принимать следующие значения (сам адрес при прямом переходе находится непосредственно в команде, а при косвенном — в регистре или ячейке памяти):

NEAR PTR — прямой переход на метку внутри текущего сегмента кода, при этом модифицируется только регистр EIP/IP (в зависимости от заданного типа сегмента кода use16 или use32) на основе указанного в команде адреса (метки) или выражения, использующего символ извлечения значения счетчика адреса команд ($);

FAR PTR — прямой переход на метку в другом сегменте кода, при этом адрес перехода задается в виде непосредственного операнда или адреса (метки) и состоит из 16-разрядного селектора и 16/32-разрядного смещения, которые загружаются, соответственно, в регистры CS и EIP/IP;

WORD PTR — косвенный переход на метку внутри текущего сегмента кода, при этом модифицируется (значением смещения размером 16 или 32 бита из памяти по указанному в команде адресу или из регистра) только регистр EIP/IP;

DWORD PTR — косвенный переход на метку в другом сегменте кода, при этом модифицируются (значением из памяти — и только из памяти, из регистра нельзя) оба регистра, CS и EIP/IP (первое слово/двойное слово адреса перехода, представляющее собой смещение, загружается в EIP/IP; второе/третье слово — в CS).

Команда безусловного перехода

Синтаксис команды безусловного перехода без сохранения информации о точке

возврата:

jmp [модификатор] адрес_перехода

Здесь адрес_перехода представляет метку или адрес области памяти, в которой находится указатель перехода.

Всего в системе команд процессора есть несколько кодов машинных команд безусловного перехода JMP. Их различия определяются дальностью перехода и способом задания целевого адреса. Дальность перехода определяется местоположением операнда адрес_перехода. Этот адрес может находиться в текущем сегменте кода или в некотором другом сегменте. В первом случае переход называется внутрисегментным, или близким, во втором — межсегментным, или дальним.

Внутрисегментный переход предполагает, что изменяется только содержимое регистра EIP/IP. Можно выделить три варианта внутрисегментного использования команды JMP:

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

-прямой переход;

-косвенный переход.

Прямой короткий внутрисегментный переход применяется, когда расстояние от команды JMP до адреса перехода не превышает -128 или +127 байт. В этом случае транслятор ассемблера формирует машинную команду безусловного перехода длиной всего два байта (размер обычной команды внутрисегментного безусловного перехода составляет три байта). Первый байт в этой команде — код операции, значение которого говорит о том, что процессор должен особым образом трактовать второй байт команды. Значение второго байта вычисляется транслятором как разность между значением смещения команды, следующей за JMP, и значением адреса перехода. При осуществлении прямого короткого перехода нужно иметь в виду следующий важный момент, связанный с местоположением адреса перехода и самой команды JMP. Если адрес перехода расположен до команды JMP, то ассемблер формирует короткую команду безусловного перехода без дополнительных указаний. Если адрес перехода расположен после команды JMP, транслятор не может сам определить, что переход короткий, так как у него еще нет информации об адресе перехода. Для оказания помощи компилятору в формировании команды короткого безусловного перехода в дополнение к ранее упомянутым модификаторам используют модификатор SHORT PTR:

jmp short ptr ml

... ;не более 35-40 команд (127 байт)

ml:

Еще вариант:

ml:

...;не более 35-40 команд (-128 байт)

jmp ml

Прямой внутрисегментный переход отличается от прямого короткого внутрисегментного перехода тем, что длина машинной команды JMP в этом случае составляет три байта. Увеличение длины связано с тем, что поле адреса перехода в машинной команде JMP расширяется до двух байтов, а это, в свою очередь, позволяет производить переходы в пределах 64 Кбайт относительно следующей за JMP команды:

ml:

... расстояние более 128 байт и менее 64 Кбайт

jmp ml

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

lea bx.ml

jmp bx ;адрес перехода в регистре bх

ml:

.data

addrjnl dw ml

.code

;…

jmp addr_ml ;адрес перехода в ячейке памяти addrjnl

mi:

Еще несколько вариантов косвенного внутрисегментного перехода:

<1>…

<2>.data

<3>addr dw ml

<4> dw m2

<5>…

<6>.code

<7>…

<8>cycl:

<9>movsi,0

<10>jmpaddr[si];адрес перехода в слове памятиaddr+(si)

<11>…

<12>mov si.2

<13>jmp cycl

<14>ml:

<15>…

<16>m2:

<17>…

В этом примере одна команда JMP (строка 10) может выполнять переходы на разные метки. Выбор конкретной метки перехода определяется содержимым регистра SI. Операнд команды JMP определяет адрес перехода косвенно после вычисления выражения addr+(SI).

<l>. . .

<2>.data

<3>addr dw ml

<4>. . .

<5>.code

<6>...

<7> lea si ,addr

<8> jmp near ptr [si ] ;адрес перехода в ячейке памяти addr

<9>…

<10>m1:

В данном случае указание модификатора NEAR PTR обязательно, так как, в отличие от предыдущего способа, адрес ячейки памяти addr с адресом перехода транслятору передается неявно (строки 3, 7 и 8), и, не имея информации о метке, он не может определить, какой именно переход осуществляется — внутрисегментный или межсегментный. Межсегментный переход предполагает другой формат машинной команды JM Р. При осуществлении межсегментного перехода кроме регистра EIP/IP

модифицируется также регистр CS. Аналогично внутрисегментному переходу, межсегментный переход поддерживают два варианта команд безусловного перехода:

прямой и косвенный.

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

seg_l segment

;…

jmp far ptr m2 ;здесь far обязательно

;…

ml label far

;…

seg_l ends

seg_2 segment

;…

m2 label far

jmp ml ;здесь far необязательно

Рассматривая этот пример, обратите внимание на модификатор FAR PTR в команде JMP. Его необходимость объясняется все той же логикой работы однопроходного транслятора. Если описание метки (метка ml) встречается в исходном тексте программы раньше, чем соответствующая ей команда перехода, то задание модификатора необязательно, так как транслятор все знает о данной метке и сам формирует нужную пятибайтовую форму команды безусловного перехода. В случае, когда команда перехода встречается до описания соответствующей метки, транслятор не имеет еще никакой информации о метке, и модификатор FAR PTR в команде JMP опускать нельзя, так как транслятор не знает, какую форму команды формировать — трехбайтную или пятибайтную. Без специального указания модификатора транслятор будет формировать трехбайтную команду внутрисегментного перехода.

Команда косвенного межсегментного перехода в качестве операнда имеет адрес области памяти, в которой содержатся смещение и сегментная часть целевого адреса перехода:

data segment

addrjnl dd ml ;в поле addr_ml значения смещения

;и адреса сегмента метки ml

data ends

code_l segment

;…

jmp ml

;…

code_l ends

code_2 segment

;…

ml label far

mov ax.bx

;…

code_2 ends

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

data segment

addr_ml dd ml ;в поле addr_ml значения смещения

;и адреса сегмента метки ml

data ends

code_l segment

;…

lea bx,addrjnl

jmp dword ptr[bx]

;…

code_l ends

code_2 segment

;…

ml label far

mov ax.bx

;…

code 2 ends

Таким образом, модификаторы SHORT PTR, NEAR PTR и WORD PTR применяются для организации внутрисегментных переходов, a FAR PTR и DWORD PTR — межсегментных.

Для полной ясности нужно еще раз подчеркнуть, что если тип сегмента — use32, то в тех местах, где речь шла о регистре IP, можно использовать регистр EIP и, соответственно, размеры полей смещения увеличить до 32 битов.

Соседние файлы в папке Лекция 6