5.5. Команды переходов
Машинные команды выполняются в порядке расположения их в памяти. Но естественный порядок нередко приходиться нарушать, чтобы следующей выполнялась не очередная команда программы, а иная. Такую возможность обеспечивают команды перехода. Переходы различают условные и безусловные. Если переход делается при выполнении некоторого условия, такой переход называется условным, а если независимо от условий, то это безусловный переход. Флаги команды перехода не изменяют.
Команда безусловного перехода JMP выполняет безусловный ближний (внутрисегментный) и дальний (межсегментный) переход по указанному адресу (табл. 47). Ближние переходы осуществляются с применением относительной (с 8- или 16-разрядным отклонением) и косвенной адресации, дальние – с применением прямой и косвенной адресации.
Табл. 47. Команда JMP.
Код
|
Инструкция
|
Описание
|
EB cb
|
JMP rel8
|
Безусловный короткий переход.
|
E9 cw
|
JMP rel16
|
Безусловный ближний переход.
|
FF /4
|
JMP r/m16
|
Безусловный ближний косвенный переход.
|
EA cd
|
JMP ptr16:16
|
Безусловный дальний переход.
|
FF /5
|
JMP m16:16
|
Безусловный дальний косвенный переход.
|
Операнд указывает адрес перехода, т.е. адрес команды, которая должна быть выполнена следующей. Обычно указывается метка команды, на которую следует передать управление. Непосредственный операнд указывать нельзя. Пример прямого перехода:
JMP L ; следующей будет выполняться команда с меткой L
...
L:...
Регистр указателя команд IP хранит адрес команды, которая должна быть выполнена следующей. Поэтому переход по некоторому адресу означает запись данного адреса в регистр IP. Однако команда прямого перехода устроена так, что в ней указывается не этот адрес, а разность между ним и адресом команды перехода. Действие команды перехода заключается в прибавлении этой величины к текущему значению регистра IP.
Выгода от указывания не адреса перехода, а расстояния от команды перехода заключается в экономии памяти. Если в команде указывать сам адрес перехода, то на него придется всегда отводить слово. В большинстве случаев переходы делаются на команды, расположенные недалеко от команд перехода, поэтому разность между адресами двух команд, как правило, небольшая, и достаточно одного байта.
Существуют две команды прямого перехода. В первой команде относительный адрес перехода задается в виде байта (короткий переход), а в другой – в виде слова (длинный переход). В каждой из этих команд операнд рассматривается как целое со знаком, поэтому при сложении его с IP значение регистра может, как увеличиться, так и уменьшиться, т.е. возможен переход по ссылке вперед, и переход по ссылке назад.
Встречая команду перехода, ассемблер вычисляет разность между адресом метки и адресом команды перехода, и оценивает величину этой разности. Если она укладывается в байт, ассемблер формирует машинную команду короткого перехода (1 байт), иначе – формирует команду длинного перехода (2 байта). Однако сделать такой выбор ассемблер в состоянии, если метка была описана до команды перехода, т.е. имеет место переход по ссылке назад.
Если в команде перехода указана ссылка вперед, то ассемблер не сможет оценить величину разности. В результате ассемблер не определит, какой переход – короткий или длинный, а потому на всякий случай сформирует команду длинного перехода.
Такой способ трансляции переходов не всегда выгоден: если метка окажется близко расположенной, то будет потерян один байт. Для указания короткого перехода существует оператор SHORT, который ставится в команде перехода перед меткой. В этом случае ассемблер формирует машинную команду короткого перехода:
JMP L ; длинный переход
JMP SHORT L ; короткий переход
Если указан оператор SHORT, но переход оказался длинным, ассемблер зафиксирует ошибку. При указании оператора перед меткой, описанной ранее, ассемблер проигнорирует его.
Косвенный переход является разновидностью безусловного. Он используются, когда адрес перехода известен только во время исполнения. В этом случае в команде перехода указывается не адрес перехода, а место, где он находится. Адрес может находиться в регистре общего назначения или занимать слово памяти. Полученный адрес рассматривается как «настоящий», а не отсчитанный от команды перехода. Примеры косвенных переходов:
A DW L
JMP A ; goto [A] = goto L
MOV DX, A ; DX = L
JMP DX ; goto [DX] = goto L
Do'stlaringiz bilan baham: |