В ряде случаев возникает необходимость в пересылке строки в обратном порядке, начиная не с первого, а с последнего ее эле­мента. Например, требуется переслать строку, содержащую 10 байт и расположенную в памяти, с относительного адреса (SI) = 200 по (SI) = 209 в область памяти с относительного ад­реса (DI)=205 no (DI) =214. Ясно, что такую пересылку нель­зя выполнять начиная с первого элемента, так как области па­мяти с исходной строкой и строкой-результатом перекрываются и первая же пересылка «испортит» значение пятого элемента ис­ходной строки. Требуемую пересылку строк можно осуществить начиная с последнего элемента исходной строки. В этом случае следует установить начальные адреса элементов строк равными (SI) =205 и (DI) =214. Кроме того, при пересылке каждого элемента необходимо не увеличивать, а уменьшать на единицу содержимое индексных регистров SI и DI. Направление переда­чи устанавливается с помощью флага DF: при значении DF=1 происходит автодекрементирование индексных регистров, а при значении DF=0 - автоинкрементирование.

Когда в качестве элементов строк используются не байты, а слова, соответствующее увеличение или уменьшение значений индексных регистров осуществляется на два, т. е. при DF=1: SI = SI - 2; DI = DI - 2, а при DF=0: SI = SI + 2, DI = DI + 2.

Кроме команды MOVS для действия со строками имеется еще четыре команды: CMPS (сравнение элементов строк), SCAS (сканирование элементов строки), LODS (загрузка эле­мента строки) и STOS (заполнение элемента строки).

НЕ нашли? Не то? Что вы ищете?

Команда CMPS позволяет осуществить поэлементное сравне­ние двух строк, одна из которых располагается в памяти с отно­сительного адреса, указанного в SI, а вторая - с относительного адреса, указанного в DI. По команде CMPS производится вы­читание элемента строки с адресом в SI из элемента строки с ад­ресом в DI. Как обычно, при выполнении операции сравнения результат вычитания не фиксируется, а устанавливаются соот­ветствующие значения флагов, по которым определяется резуль­тат сравнения. По аналогии с командой MOVS при сравнении изменяются значения индексных регистров по правилу: SI = SI ± А; DI = DI ± A, где « + » - используется при DF=0; «-» - при DF=1; А=1- при w = 0; А = 2 при w=1.

Для циклического повторения команды CMPS используется префикс повторения REPNE/REPNZ или REPE/REPZ.

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

Образцовый элемент загружается в AL и затем организуется цикл сканирования с использованием префикса повторения REPE/REPZ. Как и при выполнении предыдущих команд, каж­дый раз по команде SCAS производится автоинкремент (или автодекремент) адреса элемента: (DI) = (DI) ± A.

Две следующие команды LODS (загрузка элемента строки) и STOS (запись элемента строки) позволяют загружать элемен­ты строки в аккумулятор и записывать содержимое аккумулято­ра в строку. При выполнении этих команд осуществляется под­готовка адреса следующего элемента строки, т. е. модифициру­ется содержимое соответствующего индексного регистра. Однако повторение команды LODS обычно не используется, а повторе­ние команды STOS, организуемое с помощью префикса REP, применяется при загрузке строки константой, предварительно помещенной в аккумулятор.

Рассмотренные выше команды работы со строками реализуют относительно простые операции, на базе которых можно органи­зовать более сложные операции обработки строк.

1.8. Команды передачи управления

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

Команды безусловных переходов. Включают три мнемокода: JMP (безусловный переход), CALL (вызов подпрограммы) и RET (возврат из подпрограммы).

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

Первый формат обеспечивает переход в произвольную точку программы внутри текущего программного сегмента, для чего к содержимому IP добавляется в дополнительном коде 16-разряд­ное смещение, старший разряд которого является знаковым. Вто­рой, укороченный формат позволяет перейти к точке программы, отстоящей не более чем на -128-f-127 адресов от команды JMP. Наконец, третий формат осуществляет загрузку указателя команд 16-разрядным числом, которое размещено по исполни­тельному адресу ЕА, определяемому постбайтом. Этот переход называется косвенным, так как используется косвенная адреса­ция.

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

Четвертый формат определяет прямой межсегментный пере­ход, при котором во втором и третьем байтах формата указан относительный адрес точки перехода, а в четвертом и пятом бай­тах - новое значение CS. Пятый формат с помощью постбайта позволяет определить исполнительный адрес ЕА, по которому на­ходится относительный адрес точки перехода (в байтах памяти с адресами ЕА, ЕА+1), и новое значение CS (в байтах памяти ЕА+2, ЕА+3).

Команда CALL позволяет вызвать подпрограмму, располо­женную как в текущем программном сегменте, так и в другой области памяти. Она имеет такие же форматы, что и команда JMP, за исключением укороченного. В отличие от команды JMP аналогичного формата по команде CALL перед изменением зна­чений IP или IP и CS происходит автоматическая запись в стек текущих значений этих регистров, что обеспечивает запомина­ние точки возврата из подпрограммы.

Для возврата из подпрограммы используется команда RET, под действием которой происходит передача управления по ад­ресу возврата, занесенному в стек при выполнении предыдущей команды CALL. При возврате из подпрограмм, расположенных в текущем программном сегменте, применяются первые два фор­мата команды RET, причем второй формат отличается от перво­го тем, что к содержимому указателя стека добавляется констан­та, записанная во 2-м и 3-м байтах команды. Это позволяет одновременно с возвратом из подпрограммы сбрасывать пара­метры, записанные в стек при выполнении этой подпрограммы и не используемые в дальнейшем.

Для межсегментного возврата применяются третий и четвер­тый форматы RET, которые обеспечивают восстановление содер­жимого как указателя команд, так и программного сегмента.

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

В мнемокодах команд условных переходов при сравнении чи­сел со знаком для обозначения условия «больше» используется буква G (Greater - больше), а для обозначения - «меньше» буква L (Less - меньше). Для аналогичных условий при сравне­нии чисел без знака используются соответственно буквы A (Abo­ve- над) и В (Below - под). Условие равенства обозначается буквой Е (Equal - равно), а невыполнение некоторого условия - буквой N (Not - не). Следует отметить, что допускается исползование двух различных мнемокодов для каждой команды; на­пример, мнемокоды JL и JNGF - эквивалентны, поскольку ус­ловия «меньше» и «не больше или равно» - идентичны.

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

Таблица 1.4

Мнемокод команды

Условие

Значение флагов

Для чисел со знаком

JL/JNGE

Меньше/не больше или равно

SF + OF = l

JNL/JGE

Не меньше/больше или равно

SF + OF = 0

JG/JNLE

Больше/не меньше или равно

(SF + OF) V ZF = 0

JNG/JLE

Не больше/меньше или равно

Для чисел без знака

(SF + OF) V ZF = l

JB/JNAE

Меньше/не больше или равно

CF = 1

JNB/JAE

Не меньше/больше или равно

CF = 0

JA/JNBE

Больше

CF V ZF = 0

JNA/JBE

Не больше

Для прочих данных

CF V ZF = 1

JE/JZ

Равно/по нулю

ZF = 1

JNE/JNZ

Не равно/по нулю

ZF = 0

JS

По минусу

SF = 1

JNS

По плюсу

SF = 0

JO

По переполнению

OF = l

JNO

По отсутствию переполнения

OF = 0

JP/JPE

По четному паритету

PF = 1

JNP/JPO

По нечетному паритету

PF = 0

Все команды условных переходов имеют одинаковый двух­байтовый формат, в первом байте которого задается код опера­ции (КОП), а во втором - 8-разрядное смещение, которое рас­сматривается как число со знаком и, следовательно, позволяет осуществлять изменение адреса в диапазоне от -128 до +127. При необходимости более отдаленного («дальнего») перехода по выполнению условия используется дополнительно команда безусловного перехода.

Время выполнения каждой из команд условных переходов указано для двух случаев: 1) условие выполнено и управление действительно передается в соответствии со смещением, 2) ус­ловие не выполнено, так что управление передается следующей команде.

Команды организации циклов. Введены в ЦП для удобства выполнения вычислительных циклов. К ним относятся следующие мнемокоды: LOOP (цикл, пока (СХ) не равно 0), LOOPNZ/LOOPNE (цикл, пока не нуль/не равно), LOOPZ/LOOPE (цикл, пока нуль/равно) и JCXZ (переход по нулю в СХ). Каждая из этих команд имеет двухбайтовый формат, во втором байте кото­рого указывается 8-разрядное смещение, используемое для орга­низации перехода. Это смещение рассматривается как число со знаком и перед вычислением адреса перехода оно расширяется со знаком до 16 разрядов.

Используя команды циклов совместно с командами манипу­ляции элементами строк, можно составлять достаточно сложные программы преобразования строк. Рассмотрим пример составле­ния программы для перевода строки данных, записанных в шестнадцатеричной системе счисления, в некоторый код, для которого перекодировочная таблица находится в памяти с начального ад­реса, указанного в ВХ, как это требуется для использования команды табличного преобразования кодов XLAT. Пусть далее исходная строка содержит 80 элементов и находится в памяти с относительного начального адреса 100, а строка-результат дол­жна быть размещена с относительного адреса 200. Программа, выполняющая перекодировку исходной строки в строку-резуль­тат, при значении флага направления DF=0 будет иметь вид:

MOV SI,100
MOV DI,200
MOV
СХ , 80

TRANSLATE: LODS

XLAT

STOS

LOOP TRANSLATE

Здесь использована команда табличного преобразования кодов XLAT, описанная в 1.2.

Команды прерывания. Включают три мнемокода: INT (пре­рывание), INTO (прерывание при переполнении) и IRET (воз­врат из прерывания).

Команда прерывания INT при v = 1 имеет двухбайтовый фор­мат, второй байт которого содержит 8-разрядное число, определя­ющее тип (type) или уровень прерывания. По команде INT type процессор переходит к выполнению программы обслуживания прерывания указанного уровня, причем автоматически выполня­ются действия, необходимые для обеспечения возврата в точку прерывания. Эти действия состоят в следующем: содержимое регистра флагов F записывается в стек (PUSHF), сбрасывают­ся флаги IF и TF, текущие значения регистра CS и указателя команд IP записываются в стек.

Для определения начального адреса программы обслужива­ния в соответствии со значением type используется таблица уровней прерывания. Для каждого из 256 уровней прерываний в этой таблице от­ведено по четыре байта: первые два байта определяют значение указателя команд IP, вторые - значение сегментного регистра CS. Эта четверка байтов определяет начальные адреса программ обслуживания (пары значений CS, IP), которые должны быть предварительно записаны в ячейки памяти по абсолютным адре­сам 0-3FFH. Адрес таблицы, соответствующий указанному в команде INT type уровню прерывания, определяется в ЦП сле­дующим образом. После запоминания в стеке текущих значений CS и ГР осуществляются загрузки: CS = type x 4 + 2 и IP = type x 4. Новые значения CS и IP, взятые соответственно из ячеек с адресами type x 4 + 2 и type x 4, определяют начальный адрес требуемой программы обслуживания.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27