Условные переходы
Условныепереходыосуществляютпереходпоцелевомуадресувслучаевыполненияопределенного условия, задаваемого состоянием флагов процессора. Ниже, в таблице, описаны все возможные команды условных переходов процессора 8086.
Таблица 4.1 ― Кодировка адресов регистров
Условные переходы требуют целевого адреса – метки, обозначающей место в программе, с которого она продолжит исполняться в случае выполнения заданного условия. Метка должна находиться в пределах –128…+127 байт от адреса следующей инструкции. В случае нарушения данного условия ассемблер, во время компиляции, сообщит о соответствующей ошибке. Приведем коротенький пример. Предположим, что подпрограмма должна возвращать 1 в регистре CX, если AX=BX, или 0, если AX< > BX: PROCRegEqual mov cx, 1; Записать 1 в CX cmp ax, bx; Сравнение AX с BX je Continue; Переход, если AX=BX xor cx, cx; Иначе, установить CX в 0 Continue: ret; Возврат в вызывающую программу ENDPRegEqual Каквидноизтаблицыкомандусловныхпереходов, некоторыеизних, хотяиимеют разныемнемоники, выполняютсяприодинаковомсостояниифлаговпроцессора.Можно взаимозаменяемоиспользоватьлюбоеизэтихмнемоническихназваний: например, jeиjz ассемблируютсяводинаковыемашинныекоды.Этопозволяетсделатьпрограммирование болеепростым, т.к.вкаждомконкретномслучае можнозаписатькомандусоответствующую сформулированному условию перехода, не задумываясь о том, какие флаги процессора должны повлиятьнапереход.Этожепозволяетсделатьпрограммуболееудобнойдлячтенияи понимания. Использование условных переходов Для правильного использования условных переходовнеобходиморазличать случаи использования условийвыше-ниже и меньше-больше. Для этого необходимо запомнить следующее правило: Используйте переходы выше-ниже, такие как ja и jbe, для беззнаковых значений. Используйте переходы меньше-больше, такие как jle и jg, для значений со знаком. Вследствие особенностей арифметических операций с двоичными значениями, выражаемыми с помощьюфиксированногоколичествабитов, между сравнениемзнаковых и беззнаковых величин существуют важные различия. Следующие примеры помогут прояснить некоторые моменты. Предположим, необходимо перейти в определенное место, если врезультате вычитания двух регистров получается значение меньше 0. В этом случае необходимо записать следующее: subax, bx; AX< -AX-BX jlNegative; ПерейтиеслиAX< BX Если при вычитании получается отрицательное значение, тогда условие jl выполняется и управление передается на адрес метки Negative. Очевидно, что если AX меньше, чем BX, тогда результатвычитанияBXизAXбудетотрицательным.Однакоеслизаменитьjlнаjb, то следующие команды работать не будут: subax, bx; AX< -AX-BX jbNegative;??? Условныепереходытипавыше-нижепроверяютрезультатысравненийидругих операцийнабеззнаковых(положительных)значениях.ДажееслиBXбольше, чемAX, результатвычитаниябеззнаковогоBXизAXвсеравноостанетсябеззнаковымзначением. Чтобыпроверить, являетсялибеззнаковоезначениеAXбольшим, чембеззнаковоеBX, необходимо записать: cmp ax, bx; Беззнаковое AX> BX? jaGreater; Перейти, еслиAX> BX Командаja(переход, есливыше)корректнопроверяетрезультатсравнениядвух беззнаковых значений. Переход происходит только тогда, когда AX больше, чем BX. Если AXниже или равен BX, тогда переход не выполняется. С другой стороны, если AX и BX являются значениями со знаком, тогда в этом случае команда ja не подходит – необходимо использовать условный переход jg. Ограничения при использовании условных переходов Всеусловныепереходыимеютодносущественноеограничение: онимогутпередавать управлениетольконарасстояния–128…+127байтотадресакоманды, следующей непосредственнозакомандойперехода.Ассемблерсообщаетобошибке, еслиимеетместо попытка перейти на большее расстояние. Расстояниедоцелевойточкиусловногопереходавинтервалеот–128до+127байт называется смещением – значение вычисляемое ассемблером от метки, которую вы поставили в тексте программы. Смещение не является настоящим адресом целевой метки, оно вставляется в машинныйкодданнойкомандыперехода.Вамникогданепридетсявычислятьсмещение вручную, но вы должны знать, что так как целевой адрес выражается через смещение, условные переходыобладаютсвойствомодинакововыполнятьсявлюбомместепамяти, т.е.код, использующийтолькоусловныепереходы, можетисполнятьсявлюбомместепамяти.Он перемещаем. Ограничениенадиапазонсмещенияявляетсянеприятнойдеталью, ноегоможнов некотором роде обойти, воспользовавшись комбинацией условного и безусловного переходов. Например, программадолжнапереходитьна меткуError, расположеннуюдалеечемна127 байт от команды перехода, если DX равен 1. В этом случае можно записать: cmpdx, 1; DX =1? jneContinue; Переход, еслиDX< > 1 jmpError; Ошибка (DX=1) Continue: …; Продолжение программы, если нет ошибок. более 127 байт … Error:
|