Иллюстрированный самоучитель по Assembler

Переходы

В первом варианте, использованном в приведенном выше фрагменте, указано, через какой сегментный регистр надлежит обращаться к ячейке go_addr, содержащей адрес перехода. Здесь допустима замена сегмента, если сегмент с ячейкой go_addr адресуется через другой сегментный регистр, например, ES или CS.

Во втором варианте подчеркивается, что переход осуществляется через ячейку размером в одно слово и, следовательно, является ближним. Ячейка go_addr могла быть объявлена с помощью директивы dd и содержать полный двухсловный адрес перехода, требуемый для реализации дальнего перехода. Однако ею можно воспользоваться и для ближнего перехода. Описатель word ptr перед именем ячейки с адресом перехода заставляет транслятор считать, что она имеет размер 1 слово (независимо от того, как она была объявлена), и что переход, следовательно, является ближним.

Наконец, возможен и самый простой, третий вариант, который совпадает по форме с прямым переходом, но, тем не менее, является косвенным, так как символическое обозначение go_addr является именем поля данных, а не программной меткой. В этом варианте предполагается, что сегмент, в котором находится ячейка go_addr, адресуется по умолчанию через регистр DS, хотя, как и во всех таких случаях, допустима замена сегмента. Тип перехода (ближний или дальний) определяется, исходя из размера ячейки go_addr. Однако этот вариант не всегда возможен.

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

jmp go_addr

Было уже известно, что собой представляет имя go_addr. Этого можно добиться двумя способами. Первый – расположить сегмент данных до сегмента команд, а не после, как в приведенном выше примере. Второй – заставить транслятор обрабатывать исходный текст программы не один раз, как он это делает по умолчанию, а несколько. Число проходов для транслятора TASM можно задать при его вызове с помощью ключа /m#, где # – требуемое число проходов. В нашем случае достаточно двух проходов.

В приведенных примерах адрес поля памяти с адресом точки перехода задавался непосредственно в коде команды косвенного перехода. Однако этот адрес можно задать и в одном из регистров общего назначения (ВХ, SI или DI). Для приведенного выше примера косвенного перехода в точку go, адрес которой находится в ячейке go_addr в сегменте данных, перс-ход с использованием косвенной регистровой адресации может выглядеть следующим образом:

mov BX, offset go_addr;В ВХ смещение поля с адресом перехода
jmp [BX];Переход в точку gо

Особенно большие возможности предоставляет методика косвенного перехода с использованием базово-индексной адресации через пары регистров, например, [BX][SI] или [BX][DI]. Этот способ удобен в тех случаях, когда имеется ряд альтернативных точек перехода, выбор которых зависит от некоторых условий. В этом случае в сегменте данных создается не одно поле с адресом, а таблица адресов переходов. В базовый регистр ВХ загружается адрес этой таблицы, а в один из индексных регистров – определенный тем или иным способом индекс в этой таблице. Переход осуществляется в точку, соответствующую заданному индексу.

Структура программы, использующий такую методику, выглядит следующим образом:

code segment
mov BX, off set go_tb1;Загружаем в ВХ базовый адрес таблицы
mov SI, 4;Вычисленное каким-то
;образом смещение в таблице
jmp [BX] [SI];Если индекс =4, переход в точку go3
…
go1:;1-я точка перехода
…
gо2:;2-я точка перехода
…
gо3:;3-я точка перехода
…
code ends
data segment
go_tb1 label word;Таблица адресов переходов
go1_addr dw go1;Адрес первой альтернативной
;точки перехода
go2_addr dw go2;Адрес второй альтернативной
;точки перехода
go3_addr dw доЗ;Адрес третьей альтернативной
;точки перехода
data ends

Приведенный пример носит условный характер; в реальной программе индекс, помещаемый в регистр SI, должен вычисляться по результатам анализа некоторых условий.

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

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

mov BX, off set gol jmp BX

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

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.