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

Глава 2

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

77

Метка go может находиться в любом месте сегмента команд, как до, так и после команды jmp. В коде команды dddd обозначает слово с величи­ной относительного смещения к точке перехода от команды, следующей за командой jmp.

При выполнении команды прямого ближнего перехода процессор должен прибавить значение слова dddd к текущему значению указателя команд IP и сформировать тем самым адрес точки перехода. Что пред­ставляет собой смещение dddd? Какая это величина, со знаком или без знака' Если рассматривать смещение как величину без знака, то переход будет возможен только вперед, что, конечно, неверно. Если же смещение является величиной со знаком, то переход возможен не более, чем на полсегмента вперед или на полсегмента назад, что тоже неверно. В дей­ствительности, рассматривая вычисление адреса точки перехода, следует иметь в виду явление оборачивания, суть которого можно кратко выра­зить такими соотношениями:

FFFFh+0001h=OOOOh

OOOOh-0001h=FFFFh j

i

Если последовательно увеличивать содержимое какого-либо регистра или ячейки памяти, то, достигнув верхнего возможного предела FFFFh, число «перевалит» через эту границу, станет равным нулю и продолжит нарастать в области малых положительных чисел (1, 2, 3, и т.д.). Точно так же, если последовательно уменьшать некоторое положительное чис­ло, то оно, достигнув нуля, перейдет в область отрицательных (или, что то же самое, больших беззнаковых) чисел, проходя значения 2, 1, О, FFFFh, FFFEh и т.д.

Таким образом, при вычислении адреса точки перехода смещение следует считать числом без знака, но при этом учитывать явление обора­чивания. Если команда jmp находится где-то в начале сегмента команд, а смещение имеет величину порядка 64 К, то переход произойдет вперед, к концу сегмента. Если же команда находится в конце сегмента команд, а смещение имеет ту же величину порядка 64 К, то для определения точки перехода надо двигаться по сегменту вперед, дойти до его конца и про­должать перемещаться от начала сегмента по-прежнему вперед, пока не будет пройдено заданное в смещении число байтов. Для указанных усло­вий мы попадем в точку, находящуюся недалеко от команды jmp со сто­роны меньших адресов.

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

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

сегментный адрес и смещение. Транслятору надо сообщить, что этот пе­реход — дальний (по умолчанию команда jmp транслируется, как коман­да ближнего перехода). Это делается с помощью описателя far ptr, указы­ваемого перед именем точки перехода.

codel segment

assume CS:codel ;Сообщим транслятору, что это сегмент команд

jmp far ptr go ;Код EA dddd ssss

codel ends

code 2 segment

assume CS:code2 ;Сообщим транслятору, что это сегмент команд

go:

code2 ends

Метка go находится в другом сегменте команд этой двухсегментной программы. В коде команды ssssсегментный адрес сегмента code2, a ddddсмещение точки перехода go в сегменте команд code2.

Заметим, что при наличии в программе нескольких сегментов команд, каждый из них необходимо предварять директивой ассемблера assume СВ:1шя_сегмента, которая сообщает транслятору о том, что начался оче­редной сегмент команд. Это поможет транслятору правильно обрабаты­вать адреса меток, встречающихся в этом сегменте.

Освоив применение команд дальних переходов, мы получили возмож­ность создавать программы любой длины. Действительно, предусмотрев в конце каждого программного сегмента команду дальнего перехода на на­чало следующего, мы можем включить в программный комплекс любое число сегментов по 64 Кбайт. Единственное ограничение — чтобы они все поместились в памяти. В действительности так, конечно, не делают. Разум­нее дополнительные сегменты команд заполнить подпрограммами и вы­зывать их из основного сегмента (или друг из друга) по мере необходимо­сти. Однако и в этом случае команды вызовов подпрограмм должны быть дальними. Разновидности подпрограмм и команд их вызова будут рассмот­рены ниже.

Все виды прямых переходов требуют указания в качестве точки пере­хода программной метки. С одной стороны, это весьма наглядно; просмат­ривая текст программы, можно сразу определить, куда осуществляется переход. С другой стороны, такой переход носит статический характер — его нельзя настраивать по ходу программы. Еще более серьезный недоста­ток прямых переходов заключается в том, что они не дают возможность Перейти по известному абсолютному адресу, т.е. не позволяют обратиться ни к системным средствам, ни вообще к другим загруженным в память Программам (например, резидентным). Действительно, программы опе­рационной системы не имеют никаких меток, так как метка — это атри-

78