Пример: Глобальная сеть INTERNET
Я ищу:
На главную  |  Добавить в избранное  

Главная/

Программирование, базы данных. /

Язык макроассемблера IBM PC

←предыдущая следующая→
1 2 3 4 5 6 7 8 9 10 11 12 

следующей за ней команды, и только затем выполняется собственно команда. Для коман­ды относительного перехода это означает,  что операнд i8  прибавляется не к адресу этой команды, а к адресу команды, следующей за ней, поэто­му, к примеру, команда JMP 0  -  это переход на следующую команду про­граммы.

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

    По короткому переходу  можно передать управление только на ближай­шие команды программы  -  отстоящие от команды,  следующей за командой перехода, до 128 байтов назад  или до 127 байтов вперед.  Для перехода на более дальние команды используется

    2) Внутрисегментный относительный длинный переход.

             JMP i16       (IP:=IP+i16)

Здесь i16 обозначает непосредственный операнд размером в слово,  кото­рый рассматривается как знаковое целое от -32768 до 32767.  Этот пере­ход аналогичен короткому переходу.

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

не встречалась в тексте программы, т.е. делается переход вперед, тогда ассемблер, не зная еще адреса метки, не может определить, какую именно машинную команду относительного перехода формировать,  поэтому  он  на всякий случай выбирает команду длинного перехода.  Однако эта машинная команда занимает 3 байта,  тогда как команда  короткого перехода  -  2 байта,  и если автор программы на MASM  стремится к экономии памяти  и знает заранее, что переход вперед будет на близкую метку, то он должен сообщить об этом ассемблеру,  чтобы тот сформировал  команду короткого перехода. Такое указание делается с помощью оператора SHORT:

             JMP SHORT L

Для переходов назад оператор SHORT не нужен: уже зная адрес метки, ас­семблер сам определит вид команды относительного перехода.

    3) Внутрисегментный абсолютный косвенный переход.

             JMP r16        (IP:=[r])

       или    JMP m16        (IP:=[m16])

Здесь r16 обозначает любой 16-битовый регистр общего назначения, а m16 - адрес слова памяти. В этом регистре (слове памяти) должен находиться адрес,  по которому и будет произведен переход.  Например,  по команде JMP BX осушествляется переход по адресу, находящемуся в регистре BX.

    4) Межсегментный абсолютный прямой переход.

         JMP seg:ofs     (CS:=seg, IP:=ofs)

Здесь seg - начало (первые 16 битов начального адреса) некоторого сег­мента памяти, а ofs - смещение в этом сегменте. Пара seg:ofs определя­ет абсолютный адрес,  по которому делается переход.  В MASM  эта  пара всегда задается конструкцией  FAR PTR <метка>,  которая "говорит", что надо сделать переход по указанной метке, причем эта метка - "дальняя", из другого сегмента.  Отметим, что ассемблер сам определяет, какой это сегмент, и сам подставляет в машинную команду его начало, т.е. seg.

    5) Межсегментный абсолютный косвенный переход.

          JMP m32       (CS:=[m32+2],  IP:=[m32])

Здесь под m32 понимается адрес двойного слова памяти,  в котором нахо­дится пара seg:ofs, задающая абсолютный адрес,  по которому данная ко­манда должна выполнить переход. Напомним, что в ПК величины размером в двойное слово хранятся в "перевернутом" виде, поэтому смещение ofs на­ходится в первом слове двойного слова m32,  а смещение seg - во втором слове (по адресу m32+2).

    Команды межсегментного перехода используются тогда,  когда команды программы размещены не в одном сегменте памяти, а в нескольких (напри­мер,  команд столь много,  что в совокупности они занимают более 64Кб, т.е. более максимального размера сегмента памяти). При переходе из од­ного такого сегмента в другой необходимо менять  не только счетчик ко­манд IP,  но и содержимое регистра CS,  загружая в последний начальный адрес второго сегмента.  Такое одновременное изменение  обоих этих ре­гистров и делают команды межсегментного перехода.

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

          JMP A

- как  переход по метке A  или  как переход по адресу,  хранящемуся  в ячейке с именем A?  Кроме того,  какой это переход  - внутрисегментный или межсегментный? Ответ зависит от того, как описано имя A,  и от то­го, когда описано имя A - до или после команды перехода.

    Пусть A описано до команды перехода ("ссылка назад").  Если именем A помечена некоторая команда текущего сегмента команда  (т.е. A - мет­ка),  тогда ассемблер формирует машинную команду внутрисегментного от­носительного перехода.  Если же A -  имя  переменной,  тогда ассемблер формирует  машинную команду косвенного перехода  -  внутрисегментного, если A описано в директиве DW,  или межсегментного, если  A  описано в директиве DD.

    В случае же,  если имя A описано  после команды перехода  ("ссылка вперед"), ассемблер всегда формирует машинную команду внутрисегментно­го относительного длинного перехода.  С учетом этого имя A обязательно должно метить команду из текущего сегмента команд,  иначе будет зафик-

сирована ошибка.  Если такая трактовка ссылки вперед  не удовлетворяет автора программы, тогда он обязан с помощью оператора  SHORT  или  PTR уточнить тип имени A:

     JMP SHORT A    ;внутрисегментный короткий переход по метке

     JMP WORD PTR A   ;внутрисегментный косвенный переход

     JMP DWORD PTE A  ;межсегментный косвенный переход

    Отметим,  что переход по метке A из другого сегмента команд всегда должен указываться с помощью FAR PTR (независимо от того, описана мет­ка A до или после команды перехода):

      JMP FAR PTR A   ;межсегментный переход по метке

         1.5.2 Условные переходы.

    Практически во всех командах условного перехода проверяется значе­ние того или иного флага  (например, флага нуля ZF)  и,  если он имеет определенное значение, выполняется переход по адресу, указанному в ко­манде. Значение флага должно быть установлено предыдущей командой, на­пример, командой сравнения

             CMP op1,op2

которая вычисляет разность op1-op2, однако результат никуда не записы­вает,     а только меняет флаги,  на которые и будет реагировать  команда

условного перехода.

    В MASM команды условного перехода имеют следующую форму:

         Jxx op

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

       JE   - переход "по равно" (jump if equal)

       JL   - переход "по меньше"  (jump if less)

       JNL   - переход "по неменьше" (jump if not less)

    Особеностью  всех машинных команд условного перехода  является то, что  они  реализуют  внутрисегментный  относительный короткий переход, т.е. добавляют к счетчику команд IP свой операнд,  рассматриваемый как знаковое число от -128 до 127. В MASM

←предыдущая следующая→
1 2 3 4 5 6 7 8 9 10 11 12 


Copyright © 2005—2007 «RefStore.Ru»