Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Финогенов-основы_языка_ассемблера.doc
Скачиваний:
26
Добавлен:
17.09.2019
Размер:
3.35 Mб
Скачать

Глава 2

Основы программирования

75

2.6. Переходы

Как уже отмечалось в гл. 1, присущий процессору алгоритм выполне­ния программы заставляет его выполнять команды программы друг за дру­гом, в том порядке, как они были описаны в исходном тексте программы и содержатся в выполнимом модуле. Однако часто программисту требует­ся нарушить этот порядок, заставив процессор обойти некоторый участок программы, перейти на выполнение другой ветви или передать управле­ние подпрограмме, имея в виду после ее завершения вернуться на пре­жнее место. Все эти операции осуществляются с помощью команд пере­ходов. Переходы разделяются на безусловные, когда передача управления в другую точку программы осуществляется в безусловном порядке, неза­висимо ни от каких обстоятельств, и условные, осуществляемые или не осуществляемые в зависимости от тех или иных условий: результатов срав­нения, анализа, поиска и т.п. Безусловные переходы подразделяются на собственно переходы (без возврата в точку перехода) и вызовы подпрог­рамм (с возвратом после завершения подпрограммы).

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

Безусловные переходы осуществляются с помощью команды jmp, которая может использоваться в 5 разновидностях. Переход может быть:

прямым коротким (в пределах -128...+127 байтов);

прямым ближним (в пределах текущего сегмента команд);

прямым дальним (в другой сегмент команд);

косвенным ближним (в пределах текущего сегмента команд через ячейку

с адресом перехода);

косвенным дальним (в другой сегмент команд через ячейку с адресом

перехода).

Рассмотрим последовательно структуру программ с переходами раз­ного вида.

Прямой короткий (short) переход. Прямым называется переход, в ко­манде которого в явной форме указывается метка, на которую нужно пе­рейти. Разумеется, эта метка должна присутствовать в том же программ­ном сегменте, при этом помеченная ею команда может находиться как до, так и после команды jmp. Достоинство команды короткого перехода заключается в том, что она занимает лишь 2 байт памяти: в первом байте записывается код операции (EBh), во втором — смещение к точке пере­хода. Расстояние до точки перехода отсчитывается от очередной команды,

т.е. команды, следующей за командой jmp. Поскольку требуется обеспе­чить переход как вперед, так и назад, смещение рассматривается, как число со знаком и, следовательно, переход может быть осуществлен мак­симум на 127 байт вперед или 128 байт назад. Прямой короткий переход оформляется следующим образом:

code segment

jmp short go ;Код ЕВ dd go:

code ends

Если программа транслируется ассемблером TASM, и в строке вызова транслятора указано, что трансляция следует выполнить в два прохода

tasm /m2 p,p,p

то описатель short можно опустить, так как ассемблер сам определит, что расстояние до точки перехода укладывается в короткий переход, даже если метка go расположена после строки с командой jmp. При использо­вании транслятора MASM указание описателя short обязательно (если метка go расположена после команды jmp). Здесь проявляются незначительные различия ассемблеров разных разработчиков.

В комментарии указан код команды; dd (от displacement, смещение) обозначает байт со смещением к точке перехода от команды, следующей за командой jmp.

При выполнении команды прямого короткого перехода процессор при­бавляет значение байта dd к младшему байту текущего значения указателя команд IP (который, как уже говорилось, всегда указывает на команду, следующую за выполняемой). В результате в IP оказывается адрес точки перехода, а предложения, находящиеся между командой jmp и точкой перехода, не выполняются. Между прочим, конструкция с прямым перехо­дом вперед часто используется для того, чтобы обойти данные, которые по каким-то причинам желательно разместить в сегменте команд.

Прямой ближний (near), или внутрисегментный переход. Этот переход отличается от предыдущего только тем, что под смещение к точке пере­хода отводится целое слово. Это дает возможность осуществить переход в любую точку 64-кбайтного сегмента.

code segment

jmp go ;Код Е9 dddd go:

code ends

76