Косвенная адресация со смещением



При такой адресации исполнительный адрес ЕА определяется как сумма величины смещения и содер­жимого одного из регистров - базового или индекс­ного (ВХ, BP, SI, DI). Величина смещения может быть 8-битовым числом со знаком или 16-бито­вым числом без знака.

При использовании регистров ВХ, SI или DI за исполнительный адрес принимается перемещаемый адрес текущего сегмента данных, ба­зовый адрес которого определяется регистром сегмен­та данных DS. При использовании регистра BP за исполнительный адрес принимается перемещаемый адрес текущего стекового сегмента, базовый адрес ко­торого содержится в регистре сегмента стека SS. По­скольку в прикладных программах могут быть исполь­зованы префиксные команды, существует возможность переприсвоения исполнительных адресов относительно других сегментов памяти.

При использовании адресации данного типа поле Mod содержит двоичное число 01 или 10 в зависимо­сти от того, является ли смещение 8- или 16-битовым числом. Поле Rm представляется двоичным числом 100, 101, ПО или 111 в зависимости от того, какой используется регистр - SI, DI, BP или ВХ соответ­ственно.

Рассмотрим пример, в котором регистр сегмента стека содержит код 04В5Н. Если регистр BP содер­жит число FF10H, машинная команда С6870245 (MOV [ВР+02], 45Н) запоминает шестнадцатеричное число 45 в байте FF12H стекового сегмента. Величиной сме­щения является 8-битовое число со знаком (02), зани­мающее в команде третий байт. Исполнительный ад­рес ЕА вычисляется в результате сложения величины смещения с содержимым регистра BP (FF10H+02H). Это соответствует физическому адресу 14А62Н (4B50H-|-FF12H) памяти, который определяется ус­тройством связи. Поскольку при использовании ре­гистра BP описанная адресация обеспечивает доступ к стековому сегменту, она очень удобна для работы с конструкциями данных, использующими стек.

Индексная адресация

При такой адресации исполнительный адрес опре­деляется в результате сложения содержимого базо­вого регистра (ВХ или BP) и индексного регистра (SI или DI).

Благодаря возможности измене­ния в процессе выполнения программы содержимого базового и индексного регистров базово-индексная ад­ресация является очень гибким средством доступа к самым различным участкам компьютерной памяти. При использовании регистра ВХ исполнительный ад­рес определяется относительно сегмента данных с ба­зовым адресом, содержащимся в регистре DS. При использовании регистра BP исполнительный адрес определяется относительно сегмента стека, базовый адрес которого содержится в регистре SS. Приклад­ные программы могут включать префиксные команды, дающие возможность переприсвоить исполнительный адрес относительно других сегментов памяти компью­тера.

При базово-индексной адресации поле Mod пред­ставлено числом 00. Поле Rm представляется двоич­ным числом ООО, 001, 010 или 011 соответственно ис­пользуемой адресации [BX-f-SI], [BX+DI], [BP+SI] или [BP+DIJ.

Пусть регистр сегмента данных содержит код 04В5Н. Если регистры ВХ и SI содержат коды 1000Н и 1500Н соответственно, то машинная команда С00015 (MOV [BX-f-SI], 15H) запомнит шестнадцатеричное число 15 в байте памяти, имеющем адрес 2500Н в сегменте данных. Исполнительный адрес вычисляет­ся суммированием содержимого регистров ВХ и SI (1000Н+1500Н). Этот исполнительный адрес соответ­ствует действительному физическому адресу памяти 07050Н (4В50Н + 2500Н), устанавливаемому устрой­ством связи с магистралью.

Индексная адресация со смещением

При такой адресации исполнительный адрес опре­деляется сложением содержимого базового регистра (ВХ или BP), индексного регистра (SI или DI) и вели­чины смещения.

Как отмечалось выше, ве­личина смещения является частью команды и может быть 8-битовым числом со знаком или 16-битовым чис­лом без знака. За исполнительный адрес принимается перемещаемый адрес текущего сегмента данных или стекового сегмента в зависимости от того, какой из регистров используется - ВХ или BP соответственно.

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

При базово-индексной адресации со смещением поле Mod представляет собой двоичное число 01 или 10 в зависимости от того, определяется ли смещение 8- или 16-битовым числом. Поле Rm представляется точно так же, как и в случае базово-индексной адре­сации.

Рассмотрим пример, в котором регистр сегмента стека содержит число 04С5Н. Если регистры BP и SI содержат соответственно FF00H и 0010Н, то по ма­шинной команде С642200В (MOV [BP + SI],OBH) шестнадцатеричное число ОВ будет записано в ячейку FF30H стекового сегмента. Смещением в этом случае является 8-битовое число со знаком (шестнадцатерич­ное число 20Н). Исполнительный адрес равен сумме величины смещения и содержимого регистров BP и SI (FF00H + 0010Н + 20Н) и соответствует действи­тельному физическому адресу памяти 14В80Н (4С50Н + FF00H + 00ЮН + 20Н), определяемому устройством связи с магистралью.

Адресация строк данных

Строковые команды, такие, как MOVS (переслать строку), CMPS (сравнить строку), LODS (загрузить строку), STOS (записать строку) и SCAS (сканиро­вать строку), не используют ни один из рассмотренных Еыше типов адресации для выборки своих операндов. Содержимое индексных регистров (SI и/или DI) ис­пользуется для непосредственного указания требуемо­го участка памяти. Как следует из рис. 2.30, регистр S1 всегда используется как указатель первого байта или слова строки-источника.

Регистр DI используется как указатель первого байта или слова строки-приемника. Команда LODS предполагает использование регистра SI в качестве указателя источника. Команды STOS и SCAS исполь­зуют регистр DI в качестве указателя приемника. Команды MOVS и CMPS используют оба регистра SI и DI. Перемещаемый адрес, находящийся в регистре DI, всегда относится к текущему дополнительному сегменту. Для команд работ со строками данных мо­гут быть определены и префиксные команды, которые позволяют переприсвоить сегмент данных (для команд LODS, MOVS и CMPS) или дополнительный сегмент (для команды SCAS) другому сегменту, расположен­ному в любой части памяти 8088.

При исполнении строковой команды увеличение или уменьшение содержимого регистров SI или DI опре­деляется состоянием (нулевое или единичное) флага направления. В зависимости от того, с чем работает команда - с байтом или со словом, - содержимое ин­дексных регистров увеличивается/уменьшается соот­ветственно на 1 или 2.

19. Различают четыре типа пересылок: общего назначения, с участием аккумулятора, адреса операнда и флагов. Ни одна из команд этой группы не влияет на флаги, за исключением двух команд, которые осуществляют явную загрузку регистра флагов F.

Пересылки общего назначения. Задаются с помощью четырех мнемокодов: MOV (переслать), PUSH (занести в стек), POP (извлечь из стека) и XCHG (обменять).

Команда MOVосуществляет пересылку байта или слова из источника в место назначения. В качестве источника и места назначения может служить регистр, память или сегментный регистр. Кроме того, источником могут являться данные (константы), непосредственно представленные в формате команды. Команда MOVчасто используется в программах, что является одной из причин существования достаточно большого числа ее форматов. Выбор подходящего формата в определенной степени может оптимизировать программу по времени ее выполнения.

Команда PUSHслужит для занесения содержимого 16-разрядного источника в стек. Источником операнда может являться регистр, сегментный регистр или память. Выполнению команды предшествует формирование адреса вершины стека: (SP) = (SP) – 2.

Команда POP служит для извлечения 16-разрядного операнда из стека и пересылки его в регистр, память или сегментный регистр. Операция извлечения из стека завершается формированием нового адреса вершины стека (SP) = (SP) + 2.

Команда XCHGвызывает обмен байтами или словами между источниками. В качестве источников могут служить регистры и память. Команда имеет всего два формата, поскольку сегментные регистры не могут использоваться при обмене.

Пересылки с участием аккумулятора. Состоят из трех команд: IN(ввод), OUT (вывод) и XLAT (трансляция). В отличие от рассмотренных выше пересылок общего типа эти команды обязательно используют аккумулятор в качестве источника или места назначения операнда.

Команда IN служит для пересылки данных (байта или слова) из порта ввода в аккумулятор (в AL или АХ). Номер порта ввода может быть задан как непосредственно, во втором байте команды, так и косвенно, в регистре DX, причем только регистр DX из всех РОН может использоваться для этой цели. Если первый формат команды ввода позволяет адресоваться к 256 портам, то второй - к 216 = 65536 портам. Косвенное задание порта хотя и требует предварительной загрузки его номера в DX, однако позволяет организовывать программные циклы, в которых используется изменяющийся номер портов ввода.

Команда OUTслужит для пересылки данных (байта или слова) из аккумулятора (из ALили АХ) в порт вывода. Эта команда, как и команда IN, имеет два формата, которые определяют способ адресации порта вывода. Преимущества и недостатки использования каждого из форматов определяются теми же соображениями, что и для команды IN.

Команда XLATосуществляет табличное преобразование кодов. Таблица размером не более 256 байт размещается в памяти, а ее начальный адрес - в регистре ВХ. При выполнении этой команды содержимое AL используется в качестве относительного адреса строки таблицы, из которой байт пересылается в AL.

Пересылки адреса операнда. Включают три команды: LEA(загрузить исполнительный адрес), LDS(загрузить указатель в DS) и LES (загрузить указатель в ES). Эти команды служат средством управления механизмом адресации операндов.

По команде LEA извлекается не сам операнд, а его исполнительный адрес ЕА. Действие команды состоит в передаче вычисленного 16-разрядного адреса операнда в 16-разрядный регистр, код которого указан в поле reg. Использование команды LEA удобно при составлении подпрограмм, работающих с параметрами. В этом случае перед вызовом подпрограммы выделенный регистр загружается адресом переменной, которая предварительно записана в память в качестве параметра. Например, подпрограмма оперирует с параметром, адрес которого содержится в РОН ВХ. Если перед вызовом этой подпрограммы выполнить команду LEA BX, ALPHA, где ALPHA - имя ячейки памяти, содержащей переменную, то подпрограмма будет использовать в качестве параметра переменную из ячейки ALPHA. Если же перед вызовом подпрограммы выполнить команду LEA BX, BETA, то в качестве значения параметра подпрограмма будет использовать значение переменной из ячейки с именем BETA.

Команды LDS и LES используются, в основном, при обращении к данным, находящимся вне текущих сегментов DS или ES, так, что возникает необходимость изменить базовый адрес сегмента. Пара 16-разрядных адресов - база сегмента и смещение в сегменте, называемая указателем, предварительно загружается в память. Относительный адрес указателя определяется значениями полей mod и r/т постбайта команды LDS(или LES). Значение смещения содержится в двух первых байтах указателя, а базовый адрес сегмента - в третьем и четвертом байтах. По команде LDS(или LES) происходит обращение к указателю и осуществляется загрузка регистра DS (или ES) базовым адресом, а смещение пересылается в регистр, указанный полем reg постбайта команды.

Пересылки флагов. Включают четыре однобайтовые команды: LAHF(загрузить АН флагами), SAHF (запомнить АН в регистре F), PUSH F (занести F в стек) и POP F (извлечь из стека в F).

По команде LAHF осуществляется пересылка младшего байта регистра флагов F в АН, а по команде SAHF - обратная пересылка. Эти команды введены в систему команд ЦП для упрощения программной совместимости с ВМ80. В частности, без их использования для реализации команд PUSH PSW и POP PSW BM80 с помощью команд ЦП потребовалось бы по 9 байт памяти, а использование, например, команды LAHF позволяет при реализации команды PUSH PSW обойтись всего двумя байтами: LAHF, PUSH AX. Команда PUSHF помещает содержимое регистра F в стек, причем сначала записывается старший байт, а затем младший байт регистра F.

Принципы организации стека

Стек – это определенный динамический способ хранения данных, при котором в каждый момент времени доступ возможен только к одному из элементов, а именно к тому, который был занесен в стек последним. Часто главный принцип стека называют «первым пришел – последним ушел» (в англоязыкой литературе применяется более строгий термин LIFO: Last In – First Out).

При описании работы стека принято говорить, что он имеет фиксированное основание (нижнюю границу, дно) и подвижную вершину, через которую, собственно, и происходит запись и чтение данных.

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

Над стеком можно определить следующие операции:

  • добавление нового элемента в вершину стека (общепринят термин PUSH – «заталкивать» в стек);
  • извлечение элемента из вершины стека (POP – «выталкивать» из стека);
  • унарные операции по изменению верхнего элемента стека;
  • бинарные операции с двумя извлеченными верхними элементами; результат возвращается обратно в вершину стека.

Подчеркнем, что все приведенные выше принципы настолько общие, что пока никак не связаны с компьютерной реализацией. А теперь подумаем, как практически осуществить стек в памяти машины.

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

Учитывая, что стек может расти как в сторону увеличения, так и в сторону уменьшения адресов, а также существуют равноправные договоренности о последовательности операций при записи/чтении (например, сначала менять адрес, а потом читать данные или наоборот), возможно предложить несколько разных вариантов организации стека в ОЗУ. Тем не менее, несмотря на теоретическое разнообразие, программисты практически всегда строят стек единообразно. А именно, при заполнении стека значение указателя уменьшается, а при извлечении данных – растет. Кроме того, для записи данных используется алгоритм –(R), т.е. сначала значение указателя уменьшается, а затем происходит запись данных. Очевидно, что такой выбор предопределяет алгоритм чтения (R)+, т.е. сперва считываются данные, а затем наращивается указатель стека.

Примечание. Многочисленные рисунки, приводимые в компьютерной литературе, часто по-разному изображают положение «верха» и «низа» стека. Кроме того, и на карте памяти у одних авторов адреса растут снизу вверх, а у других – наоборот! Поэтому следует всегда быть очень внимательным, и в первую очередь обращать внимание именно на рост или убывание адресов, а не на формальное расположение элементов рисунка по вертикали.

На возможности компьютерной реализации стека могут также влиять принципы организации системы команд процессора. Так, в машинах семейства PDP в качестве регистра R для стековой адресации мог использовать любой из регистров процессора (хотя один из них – R6 – был выделен для «аппаратных нужд»), в то время как для процессоров IBM-совместимых компьютеров существует единственный регистр для работы со стеком – SP (Stack Pointer, т.е. указатель стека).

Примеры.
Пусть SP = 206 и мы рассматриваем инструкции для работы с двухбайтовыми данными. Тогда при записи в стек значение SP будет уменьшено до 204, и по этому адресу будет произведена запись требуемых данных. Если теперь считывать данные, то они будут извлечены из адреса 204, а указатель стека увеличится до 206 (фактически это означает возврат в исходное состояние).

Арифметические команды

В наборе команд имеются следующие арифметические операции: сложение, сложение с учетом флага переноса, вычитание с заемом, инкременирование, декременирование, сравнение, десятичная коррекция, умножение и деление.

В АЛУ производятся действия над целыми числами без знака. В двухоперандных операциях: сложение (ADD), сложение с переносом (ADDC) и вычитание с заемом (SUBB) аккумулятор является первым операндом и принимает результат операции. Вторым операндом может быть рабочий регистр выбранного банка рабочих регистров, регистр внутренней памяти данных с косвенно-регистровой и прямой адресацией или байт непосредственных данных. Указанные операции влияют на флаги: пеполнения, переноса, промежуточного переноса и флаг четности в слове состояния процессора (PSW).

Использование разряда переноса позволяет многократно повысить точность при операциях сложения (ADDC) и вычитания (SUBB).

Выполнение операций сложения и вычитания с учетом знака может быть осуществлено с помощью программного управления флагом переполнения (OV) регистра PSW. Флаг промежуточного переноса (АС) обеспечивает выполнение арифметических операций в двоично-десятичном коде.

Операции инкременирования и декременирования на флаги не влияют.

Операции сравнения не влияют ни на операнд назначения, ни на операнд источника, но они влияют на флаги переноса.

Существуют три арифметические операции, которые выполняются только на аккумуляторе: две команды проверки содержимого аккумулятора А (JZ, JNZ), и команда десятичной коррекции при сложении двоично-десятичных кодов.

При операции умножения содержимое аккумулятора А умножается на содержимое регистра В и результат размещается следующим образом: младший байт в регистре В, старший - в регистре А.

В случае выполнения операции деления целое от деления помещается в аккумулятор А, остаток от деления - в регистр В.

 

Логические команды

Наряду со средствами арифметических вычислений, система команд микропроцессора имеет также средства логического преобразования данных. Под логическими понимаются такие преобразования данных, в основе которых лежат правила формальной логики.
Формальная логика работает на уровне утверждений истинно и ложно. Для микропроцессора это, как правило, означает 1 и 0 соответственно.
Для компьютера язык нулей и единиц является родным, но минимальной единицей данных, с которой работают машинные команды, является байт. Однако, на системном уровне часто необходимо иметь возможность работать на предельно низком уровне — на уровне бит.

К средствам логического преобразования данных относятся логические команды и логические операции.
В связи с последним напомню, что операнд команды ассемблера в общем случае может представлять собой выражение, которое, в свою очередь, является комбинаций операторов и операндов. Среди этих операторов могут быть и операторы, реализующие логические операции над объектами выражения.

Перед подробным рассмотрением этих средств давайте посмотрим, что же представляют собой сами логические данные и какие операции над ними производятся.

23. Команды сдвига и циклического сдвига, которые представля ют собой часть логических возможностей компьютера, имеют следующие свойства:
- обрабатывают байт или слово;
- имеют доступ к регистру или к памяти;
- сдвигают влево или вправо;
- сдвигают на величину до 8 бит (для байта) и 16 бит (для слова);
- сдвигают логически (без знака) или арифметически (со знаком).
Значение сдвига на 1 может быть закодировано как непосред cтвенный операнд, значение больше 1 должно находиться в регистре CL.

Команды сдвига

При выполнении команд сдвига флаг CF всегда содержит зна чение последнего выдвинутого бита. Существуют следующие команды cдвига:
SHR ;Логический (беззнаковый) сдвиг вправо
SHL ;Логический (беззнаковый) сдвиг влево
SAR ;Арифметический сдвиг вправо
SAL ;Арифметический сдвиг влево

Следующий фрагмент иллюстрирует выполнение команды SHR:

MOV CL,03 ; AX:
MOV AX,10110111B ; 10110111
SHR AX,1 ; 01011011 ;Сдвиг вправо на 1
SHR AX,CL ; 00001011 ;Сдвиг вправо на 3
Первая команда SHR сдвигает содержимое регистра AX вправо на 1 бит. Выдвинутый в результате один бит попадает в флаг CF, а самый левый бит регистра AX заполняется нулем. Вторая команда cдвигает содержимое регистра AX еще на три бита. При этом флаг CF последовательно принимает значения 1, 1, 0, а в три левых бита в регистре AX заносятся нули.
Рассмотрим действие команд арифметического вправо SAR:

MOV CL,03 ; AX:
MOV AX,10110111B ; 10110111
SAR AX,1 ; 11011011 ;Сдвиг вправо на 1
SAR AX,CL ; 11111011 ;Сдвиг вправо на 3
Команда SAR имеет важное отличие от команды SHR: для заполне ния левого бита используется знаковый бит. Таким образом, положительные и отрицательные величины сохраняют свой знак. В приведенном примере знаковый бит содержит единицу.
При сдвигах влево правые биты заполняются нулями. Таким обpазом, результат команд сдвига SHL и SAL индентичен.
Сдвиг влево часто используется для удваивания чисел, а сдвиг вправо - для деления на 2. Эти операции осуществляются значительно быстрее, чем команды умножения или деления. Деление пополам нечетных чисел (например, 5 или 7) образует меньшие значения (2 или 3, соответственно) и устанавливаеют флаг CF в 1. Кроме того, если необходимо выполнить сдвиг на 2 бита, то использование двух команд сдвига более эффектив но, чем использование одной команды с загрузкой регистра CL значением 2.
Для проверки бита, занесенного в флаг CF используется команда JC (переход, если есть перенос).

Команды циклического сдвига

Циклический сдвиг представляет собой операцию сдвига, при которой выдвинутый бит занимает освободившийся разряд. Существуют следующие команды циклического сдвига:

ROR ;Циклический сдвиг вправо
ROL ;Циклический сдвиг влево
RCR ;Циклический сдвиг вправо с переносом
RCL ;Циклический сдвиг влево с переносом
Следующая последовательность команд иллюстрирует операцию циклического сдвига ROR:

MOV CL,03 ; BX:
MOV BX,10110111B ; 10110111
ROR BX,1 ; 11011011 ;Сдвиг вправо на 1
ROR BX,CL ; 01111011 ;Сдвиг вправо на 3

Первая команда ROR при выполнении циклического сдвига переносит правый единичный бит регистра BX в освободившуюся левую позицию. Вторая команда ROR переносит таким образом три правых бита.
В командах RCR и RCL в сдвиге участвует флаг CF. Выдвигае мый из регистра бит заносится в флаг CF, а значение CF при этом поступает в освободившуюся позицию.
Рассмотрим пример, в котором используются команды циклического и простого сдвига. Предположим, что 32-битовое значение находится в регистрах DX:AX так, что левые 16 бит лежат в регистре DX, а правые - в AX. Для умножения на 2 этого значения возможны cледующие две команды:

SHL AX,1 ;Умножение пары регистров
RCL DX,1 ; DX:AX на 2
Здесь команда SHL сдвигает все биты регистра AX влево, причем самый левый бит попадает в флаг CF. Затем команда RCL сдвигает все биты регистра DX влево и в освободившийся правый бит заносит значение из флага CF.

24. Решение о переходе может быть условным либо безусловным, это известно и по другим языкам.
«То, какая команда программы должна выполняться следующей, процессор узнает по содержимому пары регистров CS:(E)IP, в которой:
CS — регистр сегмента кода, в котором находится физический (базовый) адрес текущего сегмента кода;
EIP/IP — регистр указателя команды, в котором находится значение, представляющее собой смещение в памяти следующей выполняемой команды относительно начала текущего сегмента кода".

Классификация команд передачи

Команды безусловной передачи управления:
безусловного перехода;
вызова процедуры и возврата из процедуры;
вызова программных прерываний и возврата из программных прерываний.
Команды условной передачи управления:
перехода по результату команды сравнения;
перехода по состоянию определенного флага;
перехода по содержимому регистра ЕСХ/СХ.
Команды управления циклом:
организации цикла со счетчиком ЕСХ/СХ;
организации цикла со счетчиком ЕСХ/СХ с возможностью досрочного выхода из цикла по дополнительному условию.

Точка куда передается - метка. Она состоит из трех аттрибутов:

имя сегмента кода, где эта метка описана;
смещение — расстояние в байтах от начала сегмента кода, в котором описана метка;
тип, или атрибут расстояния, метки.
Последний атрибут может принимать два значения:
near — переход на метку возможен только в пределах сегмента кода, где эта метка описана, то есть для перехода на метку физически достаточно изменить только содержимое регистра EIP/IP;
far — переход на метку возможен только в результате межсегментной передачи управления, для осуществления которой требуется изменение содержимого как регистра EIP/IP, так и регистра CS.

Метку можно определить двумя способами:
оператором : (двоеточие);
директивой LABEL

При втором способе можно сказать, near оно или far:

ml:
mov ax,pole_1
ml label near
mov ax,pole_1

Счетчик адреса команд можно обозначить символом $, тогда он при трансляции заменяется текущим значением счетчика адреса.
Таким образом можно получить длину строки, например:
.data
;вычисление длины строки в сегменте данных
Str_Mes db "Займись делом - учи ассемблер ..."
Len_Msg=$-Str_Mes

Кроме возможности получения значения счетчика адреса компилятор позволяет при необходимости установить счетчик адреса в нужное абсолютное значение. Это делается с помощью директивы ORG:
ORG выражение

В частности, так пишут COM файлы, у которых в начале сегмент PSP, и надо писать с 256 байта данные:

codeseg segment para "code"
assume cs: codeseg,ds:codeseg,ss:codeseg
org 100h
jmp ml
;здесь описываем данные
ml:
;далее идут команды программы

Сама команда безусловного перехода:

jmp [модификатор] адрес_перехода

Виды

прямой короткий переход

jmp short ptr m1
... ;не более 35-40 команд (127 байт)
m1:

прямой переход

m1:
... расстояние более 128 байт и менее 64 Кбайт
jmp m1

косвенный переход

.data
addr dw m1
dw m2
.code
cycl:
mov si,0
jmp addr[si];адрес перехода в слове памяти addr+(si)
mov si,2
jmp cycl
m1:
m2:

Межсегментный переход предполагает другой формат машинной команды JMР. При осуществлении межсегментного перехода кроме регистра EIP/IP модифицируется также регистр CS. Аналогично внутрисегментному переходу, межсегментный переход поддерживают два варианта команд безусловного перехода: прямой и косвенный.

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

seg_l segment
jmp far ptr m2 ;здесь far обязательно
ml label far
seg_l ends
seg_2 segment
m2 label far
jmp ml ;здесь far необязательно

Косвенный

data segment
addr_m1 dd m1 ;в поле addr_m1 значения смещения
;и адреса сегмента метки m1
data ends
code_1 segment
jmp ml
code_1 ends
code_2 segment
ml label far
mov ax.bx
code_2 ends

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

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

Кажется очевидным, что возможны самые разнообразные прерывания по самым различным причинам. Поэтому с прерыванием связывают число - так называемый номер прерывания.

Этот номер однозначно соответствует тому или иному событию. Система умеет распознавать прерывания и при их возникновении запускает процедуру, соответствующую номеру прерывания.

Некоторые прерывания (первые пять по порядку номеров) зарезервированы для использования центральным процессором на случай каких-либо особых событий вроде попытки деления на нуль, переполнения и т. п.

Программы могут сами вызывать прерывания с заданным номером. Для этого они используют команду INT. Это так называемые программные прерывания. Программные прерывания не являются асинхронными, так как вызываются из программы.

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

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

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

Использование прерываний при работе с медленными внешними устройствами позволяют совместить ввод/вывод с обработкой данных в центральном процессоре. В результате этого повышается общая производительность системы.

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

Заметим, что обработчики прерываний могут сами вызывать программные прерывания, например, для получения доступа к сервису BIOS или MS-DOS.

Составление собственных программ обработки прерываний и замена стандартных обработчиков MS-DOS и BIOS является достаточно сложной задачей. Необходимо учитывать все тонкости работы аппаратуры, а также взаимодействия программного и аппаратного обеспечения. При отладке возможно разрушение операционной системы с непредсказуемыми последствиями, поэтому надо очень внимательно следить за тем, что делает ваша программа.

 


Дата добавления: 2018-05-12; просмотров: 682; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!