В ряде случаев возникает необходимость в пересылке строки в обратном порядке, начиная не с первого, а с последнего ее элемента. Например, требуется переслать строку, содержащую 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 (Above- над) и В (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 |


