Цель работы: Изучить принципы обмена информацией с использованием параллельных и последовательных каналов обмена данными.
Содержание работы: Ознакомиться по дополнительной литературе с принципами работы устройств передачи данных. Задание: написать две программы на языке ассемблера, позволяющие обмениваться информацией по указанному в варианте порту.
Варианты заданий:
1. Программы взаимодействуют через СОМ-порт. Первая посылает один байт информации (например, ASCII-код символа) в COM-порт. Вторая считывает его из COM-порта и выводит на экран.
2. Программы взаимодействуют через СОМ-порт. Первая посылает один байт информации (например, ASCII-код символа) в COM-порт и ждет подтверждение. Вторая программа считывает его из COM-порта и выводит на экран. Затем она посылает байт подтверждения (например, ASCII-код символа Y).На этом вторая программа завершает работу. Первая программа получает байт подтверждения, выводит сообщение о подтверждении на экран.
3. Программы взаимодействуют через LPT-порт. Первая посылает один байт информации (например, ASCII-код символа) в LPT-порт. Вторая считывает его из LPT-порта и выводит на экран.
4. Программы взаимодействуют через LPT-порт. Первая посылает один байт информации (например, ASCII-код символа) в LPT-порт и ждет подтверждение. Вторая программа считывает его из LPT-порта и выводит на экран. Затем она посылает байт подтверждения (например, ASCII-код символа Y).На этом вторая программа завершает работу. Первая программа получает байт подтверждения, выводит сообщение о подтверждении на экран.
Лабораторная работа № 9. Вычисления с использованием сопроцессора плавающей арифметики.
Цель работы: изучить архитектуру и систему команд арифметического сопроцессора.
Содержание работы: Написать фрагмент программы на языке ассемблера, выполняющий вычисления в соответствии с полученным вариантом задания. Фрагмент оформить в виде ассемблерной вставки в программу на языке высокого уровня. Ввод и вывод осуществлять с использованием средств языка высокого уровня.
Варианты заданий:
1. Посчитать сумму элементов с четным индексом из массива вещественных чисел.
2. Посчитать значение функции cos(0.056739), используя разложение ее в ряд Тейлора, с точностью до пятого члена этого разложения.
3. Посчитать среднее арифметическое элементов с четным индексом из массива вещественных чисел.
4. Посчитать произведение элементов с нечетным индексом из массива вещественных чисел.
5. Посчитать значение функции sin(0.056739), используя разложение ее в ряд Тейлора, с точностью до пятого члена этого разложения.
6. Получить произведение вектора-столбца и вектора-строки (одномерные массивы вещественных чисел).
7. Возвести число в заданную степень (и число и показатель степени - вещественные числа).
8. Посчитать дисперсию элементов массива вещественных чисел.
9. Найти сумму диагональных элементов квадратной матрицы вещественных чисел.
10. Найти произведение диагональных элементов квадратной матрицы вещественных чисел.
Рекомендуемая литература
1. Пильщиков В.Н. Программирование на языке ассемблера IBM PC. – М.: Диалог-МИФИ, 1994.
2. Григорьев В.Л. Микропроцессор iAPX486. Архитектура и программирование. – М.: Гранал, 1993.
3. Новиков Ю.В., Калашников О.А., Гуляев С.Э. Разработка устройств сопряжения для персонального компьютера типа IBM PC. – М.: Эком, 1997.
4. Морс С.П., Алберт Д.Д. Архитектура микропроцессора 80286. Пер. с англ. – М.: Радио и связь, 1990.
5 Нортон П., Уилтон Р. IBM PC и PS/2. Руководство по программированию. – М.: Радио и связь, 1994.
6. Фролов А.В., Фролов Г.В. Аппаратное обеспечение персонального компьютера. – М: Диалог-МИФИ, 1997.
7. Дейтел Г. Введение в операционные системы, 1987. - В 2-х томах. Том 1.
8 Кнут Д. Искусство программирования. Том 3.
9 Вирт Н. Алгоритмы и структуры данных. М.,Мир, 1989.
10А. Ахо, Хопкрофт Дж., Ульман Д. Структуры данных и алгоритмы. М.:Вильямс, 2001 г.
Приложение 1.
Справочные сведения
Таблица П1
Система команд процессора 8086
Команда | Логика | Влияние на признаки | Описание | ||||||||
O | D | I | T | S | Z | A | P | C | |||
Пересылки | |||||||||||
IN ACC, PORT | ACC Ü (PORT) | - | - | - | - | - | - | - | - | - | IN передает байт или слово из заданного порта PORT в AL или AX. Адрес порта может определяться как непосредственным байтовым значением (в диапазоне 0-255), так и с использованием косвенной адресации по регистру DX. |
LAHF | AH Ü FLAGS | - | - | - | - | - | - | - | - | - | Команда LAHF копирует пять признаков процессора 8080/8086 (SF ZF AF PF CF) в биты регистра AH с номерами 7, 6, 4, 2, 0 соответственно. Сами признаки при выполнении этой команды не меняются. |
LDS DST, SRS. | DS Ü (SRS) DST Ü (SRS + 2) | - | - | - | - | - | - | - | - | - | Команда LDS загружает в два регистра 32-битный указатель, расположенный в памяти по адресу SRS. При этом старшее слово заносится в сегментный регистр DS, а младшее слово - в базовый регистр DST. В качестве операнда DST может выступать любой 16-битный регистр, кроме сегментных.. |
LEA DST, SRS | DST Ü ADDR(SRS) | - | - | - | - | - | - | - | - | - | Команда LEA присваивает значение смещения (offset) операнда SRS (а не его значение!) операнду DST. Операнд SRS должен быть ссылкой на память, а в качестве операнда DST может выступать любой 16-битный регистр, кроме сегментных |
LES DST,SRS | ES Ü (SRS) DST Ü (SRS + 2) | - | - | - | - | - | - | - | - | - | Команда LES, загрузка указателя с использованием ES, выполняет те же действия, что и LDS, но использует при этом вместо регистра DS регистр ES |
MOV DST,SRS | DST Ü SRS | - | - | - | - | - | - | - | - | - | Пересылает по адресу DST байт или слово, находящееся по адресу SRS |
OUT PORT,ACC | (PORT) Ü ACC | - | - | - | - | - | - | - | - | - | Передает байт или слово из AL или AX в заданный порт. Адрес порта может определяться как непосредственным байтовым значением (в диапазоне 0-255), так и с использованием косвенной адресации по регистру DX. |
POP DST | DST Ü (SP) SP Ü SP + 2 | - | - | - | - | - | - | - | - | - | Команда POP пересылает слово из верхушки стека по адресу DST, затем увеличивает указатель стека SP на 2, чтобы он указывал на новую верхушку стека |
POPF | FLAGS Ü (SP) SP Ü SP + 2 | * | * | * | * | * | * | * | * | * | Команда POPF пересылает слово из верхушки стека в регистр FLAGS, изменяя значения всех признаков, затем увеличивает указатель стека SP на 2, чтобы он указывал на новую верхушку стека |
PUSH SRS | SP Ü SP - 2 (SP) Ü SRS | - | - | - | - | - | - | - | - | - | Команда PUSH уменьшает значение указателя стека SP на 2, затем пересылает операнд в новую верхушку стека. Операндом SRS не может быть 8-битный регистр. Даже если SRS указывает на байт, в стек пересылается целое слово |
PUSHF | SP Ü SP - 2 (SP) Ü FLAGS | - | - | - | - | - | - | - | - | - | Команда PUSHF уменьшает значение указателя стека SP на 2, затем пересылает слово из регистра FLAGS в верхушку стека |
SAHF | FLAGS = AH | - | - | - | - | * | * | * | * | * | Команда SAHF копирует биты регистра AH с номерами 7, 6, 4, 2 и 0 в регистр FLAGS, заменяя текущие значения признаков знака, нулевого результата, вспомогательного признака переноса, четности и переноса |
XCHG DST,SRS | DSTÛ SRS | - | - | - | - | - | - | - | - | - | Команда XCHG обменивает значения своих операндов, которые могут быть байтами или словами |
XLAT table | AL Ü (BX + AL) | - | - | - | - | - | - | - | - | - | Команда XLAT переводит байт, согласно таблице преобразований. Указатель 256-байтовой таблицы преобразований находится в BX. Байт, который нужно перевести, расположен в AL. После выполнения команды XLAT байт в AL заменяется на байт, смещенный на AL байтов от начала таблицы преобразований. |
Арифметика | |||||||||||
AAA | if (AL & 0Fh) > 9 or (AF = 1) then AL Ü AL + 6 AH Ü AH + 1 AF Ü 1; CF Ü 1 else AF Ü 0; CF Ü 0 AL Ü AL & 0Fh | ? | - | - | - | ? | ? | * | ? | * | Переводит число, записанное в младшем полубайте аккумулятора AL в число, представленное в неупакованном формате в двоично-десятичном коде (старший полубайт AL содержит нули |
AAD | AL Ü AH * 10 + AL AH Ü 0 | ? | - | - | - | * | * | ? | ? | ? | AAD переводит двухзначное число, представленное в неупакованном формате в регистре AX, из двоично-десятичного кода в двоичный, готовя число к выполнению операций деления DIV или IDIV, которые обрабатывают двоичные числа быстрее. AAD преобразует числитель в AL таким образом, чтобы результат деления был представлен числом в двоично-десятичном коде. Для того, чтобы последующая операция деления DIV давала правильный результат, необходимо, чтобы AH=0. После деления частное заносится в AL, а остаток - в AH |
AAM | AH Ü AL / 10 AL Ü AL MOD 10 | ? | - | - | - | * | * | ? | * | ? | Эта команда корректирует результат предшествующего умножения двух операндов, представленных в неупакованном двоично-десятичном коде. Двузначное неупакованное число берется из AX, проводится корректировка, и результат возвращается в AX. Для того, чтобы эта команда дала верный результат, необходимо, чтобы старшие полубайты обоих сомножителей были равны нулю |
AAS | if (AL & 0Fh) > 9 or (AF = 1) then AL Ü AL - 6 AH Ü AH - 1 AF Ü 1; CF Ü 1 else AF Ü 0; CF Ü 0 AL Ü AL & 0Fh | ? | - | - | - | ? | ? | * | ? | * | Эта команда корректирует результат предшествующего вычитания двух операндов, представленных в неупакованном двоично-десятичном коде, засчет перевода содержимого AL в двоично-десятичный код. Операнд назначения (DST) команды вычитания должен быть специфицирован так же, как AL. Старший полубайт AL всегда равен нулю |
ADC | DST Ü DST + SRS + CF | * | - | - | - | * | * | * | * | * | ADC складывает операнды, прибавляет единицу, если признак переноса CF установлен (CF=1), и засылает сумму по назначению (DST). Оба операнда могут быть байтами или словами, и оба операнда могут быть двоичными числами со знаком или без знака. Команда ADC полезна при сложении чисел, которые занимают больше 16 бит, т.к. она прибавляет перенос от предыдущей операции. |
ADD | DST Ü DST + SRS | * | - | - | - | * | * | * | * | * | ADD складывает операнды и засылает сумму по назначению (DST). Оба операнда могут быть байтами или словами, и оба операнда могут быть двоичными числами со знаком или без знака. |
CBW | if (AL < 80h) then AH Ü 0 else AH Ü FFh | - | - | - | - | - | - | - | - | - | CBW расширяет бит знака регистра AL в регистр AH. Эта команда переводит байтовую величину со знаком в эквивалентное ей слово со знаком. Эта команда положит AH равным 0FFh, если бит знака регистра AL (т.е. седьмой бит) установлен; если же седьмой бит AL не установлен, то в AH заносятся нули. Эта команда полезна для преобразования байта в слово, в первую очередь, с целью выполнения операции деления байтов. |
CMP DST,SRS | (DST - SRS) | * | - | - | - | * | * | * | * | * | CMP сравнивает два числа, вычитая операнд SRS из операнда DST, и изменяет значения признаков. CMP не изменяет сами операнды. Операндами могут быть байты или слова. |
CWD | if (AX < 8000h) then DX Ü 0 else DX Ü FFFFh | - | - | - | - | - | - | - | - | - | CWD расширяет бит знака регистра AX на весь регистр DX. Эта команда генерирует двойное слово, эквивалентное числу со знаком, находящемуся в регистре AX Эта команда положит DX равным 0FFFFh, если бит знака (15-ый бит) регистра AX установлен, и равным 0, если бит знака AX сброшен. |
DAA | if (AL & 0Fh) > 9 or (AF = 1) then AL Ü AL + 6 AF Ü 1 else AF Ü 0 if (AL > 9Fh) or (CF = 1) then AL Ü AL + 60h CF Ü 1 else CF Ü 0 | ? | - | - | - | * | * | * | * | * | Команда DAA корректирует результат предшествующего ей сложения двух упакованных десятичных операндов (заметьте, что результат должен находиться в AL). Эта команда изменяет содержимое AL так, чтобы AL содержал пару упакованных десятичных цифр. В упакованном двоично-десятичном коде каждому полубайту соответствует одна цифра; менее значащую цифру содержит младший полубайт. После деления или умножения чисел, записанных в упакованном двоично-десятичном коде, производить коррекцию нельзя. Поэтому, если Вы хотите воспользоваться операцией деления или умножения, то лучше использовать числа в неупакованном двоичнодесятичном коде. См., например, описание команды AAM (ASCII-коррекция при умножении). |
DAS | if (AL & 0Fh) > 9 or (AF = 1) then AL Ü AL - 6 AF Ü 1 else AF Ü 0 if (AL > 9Fh) or (CF = 1) then AL Ü AL - 60h CF Ü 1 else CF Ü 0 | ? | - | - | - | * | * | * | * | * | Команда DAS корректирует результат предшествующего ей вычитания двух упакованных десятичных операндов (заметьте, что результат должен находиться в AL). Эта команда изменяет содержимое AL так, чтобы AL содержал пару упакованных десятичных цифр |
DEC DST | DST Ü DST - 1 | * | - | - | - | * | * | * | * | * | Эта команда отнимает от операнда DST единицу. Операнд DST, который может быть словом или байтом, интерпретируется как двоичное число без знака |
DIV SRS | if SRS – байт AL Ü AX / SRS AH Ü remainder else AX Ü DX:AX / SRS DX Ü remainder | ? | - | - | - | ? | ? | ? | ? | ? | Эта команда выполняет деление без учета знака. Если операнд SRS является байтом, то DIV делит значение слова в AX на операнд SRS, засылая частное в AL и остаток (remainder) в AH. Если же операнд SRS является словом, то DIV делит значение двойного слова из DX:AX на операнд SRS, засылая частное в AX и остаток в DX. |
IDIV SRS | if SRS – байт AL Ü AX / SRS AH Ü remainder else AX Ü DX:AX / SRS DX Ü remainder | ? | - | - | - | ? | ? | ? | ? | ? | Эта команда выполняет деление с учетом знака. Если операнд SRS является байтом, то IDIV делит значение слова в AX на операнд SRS, засылая частное в AL и остаток (remainder) в AH. Если же операнд SRS является словом, то IDIV делит значение двойного слова из DX:AX на операнд SRS, засылая частное в AX и остаток в DX. Если результат слишком велик и не умещается в AL (соотв. AX), то генерируется прерывание INT 0 (деление на ноль), и тогда частное с остатком не определены. Микропроцессоры 80286 и 80386 могут в качестве частного после выполнения этой команды генерировать наибольшее (по абсолютной величине) негативное число (80h или 8000h), однако, 8088/8086 сгенерируют в такой ситуации прерывание INT 0. Когда генерируется прерывание INT 0, то для процессоров 80286 и 80386 запоминаемое значение CS:IP указывает на неудавшуюся команду (т.е. на команду IDIV). Для процессоров 8088/8086 CS:IP указывает, однако, на команду, следующую за неудавшейся командой IDIV. |
IMUL SRS | if SRS – байт AX Ü AL * SRS; else DX:AX Ü AX*SRS | * | - | - | - | ? | ? | ? | ? | * | Эта команда выполняет умножение с учетом знака. Если операнд SRS является байтом, то IMUL умножает операнд SRS на AL, засылая произведение в AX. Если же операнд SRS является словом, то IMUL умножает операнд SRS на AX, засылая произведение в DX:AX. Признаки переноса и переполнения CF и OF устанавливаются (=1), если старшая половина результата (т.е. AH для случая, когда SRS - байт, и DX, когда SRS - слово) содержит какую-либо значащую цифру произведения, иначе они сбрасываются (=0). |
INC DST | DST Ü DST + 1 | * | - | - | - | - | * | * | * | * | Эта команда прибавляет к операнду DST единицу. Операнд DST, который может быть словом или байтом, интерпретируется как двоичное число без знака При выполнении этой команды признак переноса CF не изменяется, поэтому если Вы хотите инкрементировать число, записанное несколькими словами, то лучше воспользоваться командами ADD и ADC. |
MUL SRS | if SRS – байт AX Ü AL * SRS else DX:AX Ü AX*SRS | * | - | - | - | ? | ? | ? | ? | * | Эта команда выполняет умножение без учета знака. Если операнд SRS является байтом, то MUL умножает операнд SRS на AL, засылая произведение в AX. Если же операнд SRS является словом, то MUL умножает операнд SRS на AX, засылая произведение в DX:AX. Признаки переноса и переполнения CF и OF устанавливаются (=1), если старшая половина результата (т.е. AH для случая, когда SRS - байт, и DX, когда SRS - слово) содержит какую-либо значащую цифру произведения, иначе они сбрасываются (=0). |
NEG DST | DST Ü – DST | * | - | - | - | * | * | * | * | * | Команда NEG вычитает операнд destinstion из 0 и засылает результат обратно в DST. Эта команда является реализацией выполнения операции нахождения дополнительного кода операнда. Операндом может быть как байт, так и слово. |
SBB DST,SRS | DST Ü DST – SRS – CF | * | - | - | - | * | * | * | * | * | Команда SBB вычитает операнд SRS из операнда DST, вычитает 1 из результата, если признак переноса установлен (т.е. если CF = 1), и засылает результат по адресу DST. Оба операнда могут быть байтами или словами, и оба операнда могут быть двоичными числами со знаком или без знака. |
SUB DST,SRS | DST Ü DST – SRS | * | - | - | - | * | * | * | * | * | Команда SUB вычитает операнд SRS из операнда DST и засылает результат по адресу DST. Оба операнда могут быть байтами или словами, и оба операнда могут быть двоичными числами со знаком или без знака. |
AND DST,SRS | DST Ü DST AND SRS | - | - | - | * | * | ? | * | AND выполняет логическое умножение побитно над своими операндами и засылает результат по назначению (DST). Оба операнда могут быть словами или байтами. | ||
NOT DST | DST Ü NOT DST | обратный код | |||||||||
OR DST,SRS | DST Ü DST OR SRS | - | - | - | * | * | ? | * | OR выполняет логическое сложение побитно над своими операндами и засылает результат по назначению (DST). Оба операнда могут быть словами или байтами. | ||
RCL DST,count | * | - | - | - | - | - | - | - | * | Команда RCL сдвигает слово или байт, находящийся по адресу DST, влево на число битовых позиций, определяемое вторым операндом, COUNT. Бит, который выскакивает за левый предел операнда DST, заносится в признак переноса CF, а старое значение CF осуществляет ротацию, в том смысле, что оно заносится в освободившийся крайний правый бит операнда DST. Число таких "битовых ротаций" определяется операндом COUNT. Если COUNT не равен 1, то признак переполнения OF не определен. Если же COUNT равен 1, тогда в OF заносится результат выполнения операции исключающего или, примененной к 2 старшим битам исходного значения операнда DST. В качестве операнда COUNT берется обычно значение в регистре CL. Если, однако, Вы хотите осуществить сдвиг лишь на одну позицию, то замените второй операнд (CL) на число 1. Микропроцессоры 80286 и 80386 ограничивают значение COUNT числом 31. Если COUNT больше, чем 31, то эти микропроцессоры используют COUNT MOD 32, чтобы получить новый COUNT в пределах 0-31. Эта верхняя граница имеет своей целью сократить тот период времени, на который будет задерживаться ответ на прерывание из-за ожидания конца выполнения команды. Несколько команд RCL, использующих 1 в качестве второго операнда, выполняются быстрее и требуют меньшего об'ема памяти, чем одна команда RCL, использующая CL в качестве операнда COUNT. Признак переполнения не определен, если операнд COUNT больше 1. | |
RCR DST,count | * | - | - | - | - | - | - | - | * | Команда RCR сдвигает слово или байт, находящийся по адресу DST, вправо на число битовых позиций, определяемое вторым операндом, COUNT. Бит, который выскакивает за правый предел операнда DST, заносится в признак переноса CF, а старое значение CF осуществляет ротацию, в том смысле, что оно заносится в освободившийся крайний левый бит операнда DST. Число таких "битовых ротаций" определяется операндом COUNT. См команду RCL. | |
ROL DST,count | * | - | - | - | - | - | - | - | * | Команда ROL сдвигает слово или байт, находящийся по адресу DST, влево на число битовых позиций, определяемое вторым операндом, COUNT. Бит, который выскакивает за левый предел операнда DST, заносится в него снова с правого края. Значение CF совпадает со значением бита, который последним был вытеснен за левый край операнда. См команду RCL. | |
ROR DST,count | * | - | - | - | - | - | - | - | * | Команда ROR сдвигает слово или байт, находящийся по адресу DST, вправо на число битовых позиций, определяемое вторым операндом, COUNT. Бит, который выскакивает за правый предел операнда DST, заносится в него снова с левого края. Значение CF совпадает со значением бита, который последним был вытеснен за правый край операнда. См команду RCL. | |
SAL DST,count | * | - | - | - | * | * | ? | * | * | Команда SAL сдвигает слово или байт, находящийся по адресу DST, влево на число битовых позиций, определяемое вторым операндом, COUNT. По мере вытеснения битов за левый край операнда DST, справа в освободившиеся биты заносятся нули. Значение CF совпадает со значением бита, который последним был вытеснен за левый край операнда. См команду RCL. | |
SHL | * | - | - | - | * | * | ? | * | * | Тоже самое, что SAL | |
SAR DST,count | * | - | - | - | * | * | ? | * | * | Команда SAR сдвигает слово или байт, находящийся по адресу DST, вправо на число битовых позиций, определяемое вторым операндом, COUNT. По мере вытеснения битов за правый край операнда DST, слева в освободившиеся биты заносятся биты, совпадающие с битом знака исходного значения операнда DST. Значение CF совпадает со значением бита, который последним был вытеснен за правый край операнда. См команду RCL. | |
SHR DST,count | * | - | - | - | * | * | ? | * | * | Команда SHR сдвигает слово или байт, находящийся по адресу DST, вправо на число битовых позиций, определяемое вторым операндом, COUNT, или содержимым CL, если второй операнд опущен. По мере вытеснения битов за правый край операнда DST, слева в освободившиеся биты заносятся нули. Если бит знака сохраняет свое значение, то признак переполнения OF равен 0, иначе он равен 1. Значение CF совпадает со значением бита, который последним был вытеснен за правый край операнда. См команду RCL | |
TEST DST,SRS | (DST AND SRS) | - | - | - | * | * | ? | * | Команда TEST выполняет операцию AND над своими операндами и меняет значения признаков. Сами операнды не изменяются. Команда TEST полезна при проверке значения конкретного бита. Например, следующий кусок программы передает управление в ONE_FIVE_OFF, если биты 1 и 5 регистра AL сброшены. Значения остальных битов во внимание не принимаются. | ||
XOR DST,SRS | DST Ü DST XOR SRS | - | - | - | * | * | * | * | XOR выполняет операцию исключающего или побитно над своими операндами и засылает результат по назначению (DST). Оба операнда могут быть словами или байтами. | ||
Цепочки | |||||||||||
CMPS DST-string,SRS_string | CMP (DS:SI), (ES:DI); if DF = 0 SI Ü SI + n; n = 1 для байта, 2 для слова DI Ü DI + n else SI Ü SI - n DI Ü DI – n. | * | - | - | - | * | * | * | * | * | Эта команда сравнивает два значения, вычитая байт или слово, на которое указывает ES:DI, из байта или слова, на которое указывает DS:SI, и устанавливает признаки в соответствии с результатами сравнения. Сами операнды не изменяются. После сравнения, SI и DI увеличиваются на 1 (для байтов) или 2 (для слов), если признак направления сброшен, или уменьшаются на 1 или 2, если признак направления установлен. Тем самым подготавливаются к сравнению следующие элементы обеих строк. Эта команда всегда переводится ассемблером или в CMPSB, сравнение строк из байтов, или в CMPSW, сравнение строк из слов, в зависимости от того, являются ли операнды строками из байтов или из слов. В обоих случаях Вы должны в явном виде загрузить в регистры SI и DI смещения обеих строк. |
CMPSB | |||||||||||
CMPSW | |||||||||||
LODS SRS-str | ACC Ü (DS:SI) if DF = 0 SI Ü SI + n; n = 1 для байта, 2 - для слова else SI Ü SI – n. | - | - | - | - | - | - | - | - | - | Команда LODS передает байт или слово, расположенное по адресу DS:SI в AX или AL, а также инкрементирует или декрементирует SI (в зависимости от состояния признака направления DF), чтобы указатель переместился на следующий элемент. Эта команда всегда ассемблируется или как LODSB, загрузка строки из байтов, или как LODSW, загрузка строки из слов, в зависимости от того, указывает ли SRS-str на строку байтов или на строку слов. Однако, в обоих случаях Вы должны в явном виде загрузить в регистр SI смещение строки. Хотя и разрешется использовать эту команду в повторном режиме, это почти никогда не делается, т.к. это привело бы к постоянному изменению значения в AL. |
LODSB | |||||||||||
LODSW | |||||||||||
MOVS DST,SRS | (ES:DI) Ü (DS:SI) if DF = 0 SI Ü SI + n; n = 1 для байта, 2 - для слова DI Ü DI + n else SI Ü SI - n DI Ü DI – n. | - | - | - | - | - | - | - | - | - | Эта команда пересылает байт или слово, расположенное по адресу DS:SI, по адресу ES:DI. После пересылки SI и DI инкрементируются (если признак направления сброшен) или декрементируются (если признак направления установлен),чтобы указатель переместился на следующий элемент строки. Эта команда всегда ассемблируется или как MOVSB, пересылка строки из байтов, или как MOVSW, пересылка строки из слов, в зависимости от того, является ли SRS ссылкой на строку из байтов или строку из слов. В обоих случаях Вы должны в явном виде загрузить в регистры SI и DI смещения строк SRS и DST. |
MOVSB | |||||||||||
MOVSW | |||||||||||
SCAS DST-string | CMP ACC,(ES:DI) if DF = 0 DI Ü DI + n n = 1 для байта, 2 для слова else DI Ü DI - n. | * | - | - | - | * | * | * | * | * | Эта команда сравнивает аккумулятор (AL или AX) с байтом или словом, на которое указывает ES:DI, и устанавливает признаки в соответствии с результатами сравнения. Сами операнды не изменяются. После сравнения, DI увеличивается на 1 (для байтов) или 2 (для слов), если признак направления сброшен, или уменьшается на 1 или 2, если признак направления установлен. Тем самым подготавливается к сравнению следующий элемент строки. Эта команда всегда ассемблируется или как SCASB, просмотр строки из байтов, или как SCASW, просмотр строки из слов, в зависимости от того, является ли операнд строкой из байтов или из слов. В обоих случаях Вы должны в явном виде загрузить в регистр DI смещение строки. Команда SCAS полезна в тех случаях, когда требуется найти ячейку с заданным байтом или словом. Если Вы хотите сравнить две строки из памяти поэлементно, то используйте команду CMPS |
SCASB | |||||||||||
SCASW | |||||||||||
STOS DST-string | (ES:DI) Ü ACC if DF = 0 DI Ü DI + n; n = 1 для байта, 2 - для слова else DI Ü DI - n. | - | - | - | - | - | - | -- | -- | - | Команда STOS копирует байт или слово, расположенное в AL или AX, в место памяти, на которое указывает (ES:DI), а также инкрементирует или декрементирует DI (в зависимости от состояния признака направления DF), чтобы подготовиться к копированию аккумулятора в следующую ячейку (байт или слово) памяти. Эта команда всегда ассемблируется или как STOSB, запись в строку из байтов, или как STOSW, запись в строку из слов, в зависимости от того, указывает ли DST-string на строку байтов или на строку слов. Однако, в обоих случаях Вы должны в явном виде загрузить в регистр DI смещение строки. |
STOSB | |||||||||||
STOSW | |||||||||||
REP (команда обработки строк) | while CX <> 0 выполнить КОС CX Ü CX - 1 | - | - | - | - | - | - | - | - | - | REP - это префикс, который может быть употреблен перед любой КОС (CMPS, LODS, MOVS, SCAS и STOS). Префикс REP заставляет выполняться следующую за ним КОС в повторном режиме до тех пор, пока CX не станет равным 0; CX уменьшается на 1 после каждого выполнения КОС. (Для КОС CMPS и SCAS циклический повтор прерывается также, если признак нулевого результата ZF оказывается сброшенным после очередного выполнения КОС.) Если CX с самого начала равно 0, то КОС не выполняется ни разу. Проверка о равенстве CX нулю проводится перед выполнением КОС. Проверка о равенстве ZF нулю проводится только для команд CMPS и SCAS, причем лишь после очередного выполнения КОС. Префиксы REP, REPE (повтор пока равно) и REPZ (повтор пока ноль) - все являются синонимами одного и того же префикса. Префикс REPNZ (повтор пока не ноль) похож на REP и отличается лишь тем, что для команд CMPS и SCAS повтор прекращается, когда ZF установлен, а не когда сброшен (как в REP). Префикс REP используется обычно с КОС MOVS (пересылка строки) и STOS (запись строки), его можно интерпретировать как "повторяй, пока не кончится строка". У Вас нет необходимости инициализировать ZF перед использованием повторяющихся КОС. |
Передача управления | |||||||||||
Безусловная передача управления | |||||||||||
CALL ADDRESS | if FAR CALL (внешний сегмент) PUSH CS CS Ü dest_seg PUSH IP IP Ü dest_offset | - | - | - | - | - | - | - | - | - | CALL передает управление подпрограмме, которая может находиться как внутри текущего сегмента (NEAR-proc), так и вне его (FAR-proc). Этим двум типам CALL соответствуют две различные машинные команды, и команда RET возврата из подпрограммы должна соответствовать типу команды CALL (потенциальная возможность несоответствия возникает, когда подпрограмма и команда CALL ассемблируются раздельно). Если подпрограмма находится в другом сегменте, то процессор засылает в стек сначала текущее значение CS, затем текущее значение IP (IP указывает на команду, следующую за командой CALL), а затем передает управление в подпрограмму. Если же подпрограмма находится в том же сегменте, то процессор засылает в стек сначала текущее значение IP (которое опять же указывает на команду, следующую за командой CALL), а затем передает управление в подпрограмму. CALL также может считать адрес подпрограммы из регистра или из памяти. Эта форма команды CALL называется косвенным вызовом. |
JMP target | if FAR JUMP (внешний сегмент) CS Ü dest_seg IP Ü dest_offset | - | - | - | - | - | - | - | - | - | Команда JMP всегда передает управление в место, определяемое операндом target. В отличие от команды CALL, JMP не запоминает значение IP, т.к. появление команды возврата RET не ожидается. Переход внутри сегмента может быть задан как операндом типа память, так и через 16-битный регистр. Переход во внешний сегмент может быть задан только через операнд типа память. Если ассемблер может определить, что в случае перехода внутри сегмента цель перехода находится в пределах 127 байтов от места расположения текущей команды, то ассемблер автоматически сгенерирует двухбайтовую команду (короткий переход); в противном случае сгенерируется трехбайтовый NEAR JMP. В целях генерации двухбайтовой команды Вы можете сделать "подсказку" ассемблеру, используя специальный оператор "short": JMP short near_by |
RET optional-pop-value | POP IP if FAR RETURN (внешний сегмент) POP CS SP = SP + optional-pop-value (если оно имеется | - | - | - | - | - | - | - | - | - | Команда RET передает управление из вызванной подпрограммы команде, следовавшей непосредственно за CALL, и делает это следующим образом: - пересылает слово из верхушки стека в IP; - если возврат осуществляется во внешний сегмент, то пересылает слово из новой верхушки стека в CS; - увеличивает SP на значение операнда optional-pop-value, если оно задано. Ассемблер сгенерирует возврат во внутренний сегмент, если подпрограмма, содержащая RET, будет обозначена программистом как NEAR, и возврат во внешний сегмент, - если как FAR. Операнд optional-pop-value определяет значение, которое надо прибавить к SP, что имеет смысл "освобождения" стека от "лишних" байтов (например, от входных параметров, когда они передаются подпрограмме через стек). |
Условная передача управления | |||||||||||
JA short-label | Jump if CF = 0 and ZF = 0 | - | - | - | - | - | - | - | - | - | Команда JA используется после команд CMP и SUB и передает управление по метке short-label, если первый операнд (который должен быть числом без знака) был больше, чем второй операнд (также без знака). Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. |
JAE short-label | Jump if CF = 0 | - | - | - | - | - | - | - | - | - | Команда JAE используется после команд CMP или SUB и передает управление по метке short-label, если первый операнд был больше или равен второму. (Оба операнда рассматриваются как числа без знака.) Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команда JNB, переход если не ниже, - это та же команда, что и JAE. Команду JAE, переход если выше или равно, следует использовать при сравнении чисел без знака. Команду JGE, переход если больше или равно, следует использовать при сравнении чисел со знаком. |
JB short-label. | Jump if CF = 1 | - | - | - | - | - | - | - | - | - | Команда JB используется после команд CMP и SUB и передает управление по метке short-label, если первый операнд был меньше, чем второй. (Оба операнда рассматриваются как числа без знака.) Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команды JC (переход если перенос), JB и JNAE (переход если не выше и не равно) все являются синонимами одной и той же команды. Команду JB, переход если ниже, следует использовать при сравнении чисел без знака. Команду JL, переход если меньше, следует использовать при сравнении чисел со знаком. |
JBE short-label | Jump if CF = 1 or ZF = 1 | - | - | - | - | - | - | - | - | - | Команда JBE используется после команд CMP и SUB и передает управление по метке short-label, если первый операнд был меньше или равен второму. (Оба операнда рассматриваются как числа без знака.) Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команда JNA, переход если не выше, - это та же команда, что и JBE. Команду JBE, переход если ниже или равно, следует использовать при сравнении чисел без знака. Команду JLE, переход если меньше или равно, следует использовать при сравнении чисел со знаком. |
JC short-label | Jump if CF = 1 | - | - | - | - | - | - | - | - | - | Команда JC передает управление по метке short-label, если признак переноса CF установлен (т.е. =1). Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команды JB (переход если ниже), JC и JNAE (переход если не выше и не равно) все являются синонимами одной и той же команды. Пользуйтесь командой JNC, переход если нет переноса, для перехода в том случае, когда признак переноса CF сброшен (т.е. =0). |
JCXZ short-label | Jump if CX = 0 | - | - | - | - | - | - | - | - | - | Команда JCXZ передает управление по метке short-label, если регистр CX равен 0. Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Эта команда обычно применяется в начале цикла, чтобы пропустить тело цикла, когда переменная счетчика (CX) равна нулю. |
JE short-label | Jump if ZF = 1 | - | - | - | - | - | - | - | - | - | Команда JE используется после команд CMP и SUB и передает управление по метке short-label, если первый операнд был равен второму. Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команда JZ, переход если ноль, - это та же команда, что и JE. |
: JG short-label | Jump if ZF = 0 and SF = OF | - | - | - | - | - | - | - | - | - | Команда JG используется после команд CMP или SUB и передает управление по метке short-label, если первый операнд был больше, чем второй. (Оба операнда рассматриваются как числа со знаком.) Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команда JNLE, переход если не меньше и не равно, - это та же команда, что и JG. Команду JA, переход если выше, следует использовать при сравнении чисел без знака. Команду JG, переход если больше, следует использовать при сравнении чисел со знаком. |
JGE short-label | Jump if SF = OF | - | - | - | - | - | - | - | - | - | Команда JGE используется после команд CMP или SUB и передает управление по метке short-label, если первый операнд был больше или равен второму. (Оба операнда рассматриваются как числа со знаком.) Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команда JNL, переход если не меньше, - это та же команда, что и JGE. Команду JAE, переход если выше или равно, следует использовать при сравнении чисел без знака. Команду JGE, переход если больше или равно, следует использовать при сравнении чисел со знаком. |
JL short-label | Jump if SF <> OF | Команда JL используется после команд CMP или SUB и передает управление по метке short-label, если первый операнд был меньше, чем второй. (Оба операнда рассматриваются как числа со знаком.) Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команда JNGE, переход если не больше и не равно, - это та же команда, что и JL. Команду JB, переход если ниже, следует использовать при сравнении чисел без знака. Команду JL, переход если меньше, следует использовать при сравнении чисел со знаком. | |||||||||
JLE short-label | Jump if SF <> OF or ZF = 1 | - | - | - | - | - | - | - | - | - | Команда JLE используется после команд CMP или SUB и передает управление по метке short-label, если первый операнд был меньше или равен второму. (Оба операнда рассматриваются как числа со знаком.) Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команда JNG, переход если не больше, - это та же команда, что и JLE. Команду JBE, переход если ниже или равно, следует использовать при сравнении чисел без знака. Команду JLE, переход если меньше или равно, следует использовать при сравнении чисел со знаком. |
JNA short-label | - | - | - | - | - | - | - | - | - | JNA - синоним JBE. См. описание JBE | |
JNAE short-label | - | - | - | - | - | - | - | - | - | JNAE - синоним JB. См. описание JB | |
JNB short-label | - | - | - | - | - | - | - | - | - | JNB - синоним JAE. См. описание JAE | |
JNBE short-label | - | - | - | - | - | - | - | - | - | JNBE - синоним JA. См. описание JA | |
JNC short-label | Jump if CF = 0 | - | - | - | - | - | - | - | - | - | Команда JNC передает управление по метке short-label, если признак переноса CF сброшен (т.е. =0). Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Пользуйтесь командой JC, переход если перенос, для перехода в том случае, когда признак переноса CF установлен (т.е. =1). |
JNE short-label | Jump if ZF = 0 | - | - | - | - | - | - | - | - | - | Команда JNE используется после команд CMP и SUB и передает управление по метке short-label, если первый операнд не был равен второму. Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команда JNZ, переход если не ноль, - это та же команда, что и JNE. |
JNG short-label | - | - | - | - | - | - | - | - | - | JNG - синоним JLE. См. описание JLE. | |
JNGE short-label | - | - | - | - | - | - | - | - | - | JNGE - синоним JL. См. описание JL | |
JNL short-label | - | - | - | - | - | - | - | - | - | JNL - синоним JGE. См. описание JGE. | |
JNLE short-label | - | - | - | - | - | - | - | - | - | JNLE - синоним JG. См. описание JG. | |
JNO short-label | Jump if OF = 0 | - | - | - | - | - | - | - | - | - | Команда JNO передает управление по метке short-label, если признак переполнения OF сброшен (т.е. =0). Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Пользуйтесь командой JO, переход если переполнение, для перехода в том случае, когда признак переполнения OF установлен (т.е. =1). |
JNP short-label | Jump if PF = 0 | - | - | - | - | - | - | - | - | - | Команда JNP передает управление по метке short-label, если признак четности PF сброшен (т.е. =0). Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Команда JPO, переход если нечетно, - это та же команда, что и JNP. Пользуйтесь командой JP, переход если четно, для перехода в том случае, когда признак четности PF установлен (т.е. =1). |
JNS short-label | Jump if SF = 0 | - | - | - | - | - | - | - | - | - | Команда JNS передает управление по метке short-label, если признак знака SF сброшен (т.е. =0). Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Пользуйтесь командой JS, переход если отрицательный результат, для перехода в том случае, когда признак знака SF установлен (т.е. =1). |
JNZ short-label | - | - | - | - | - | - | - | - | - | JNZ - синоним JNE. См. описание JNE. | |
JO short-label | Jump if OF = 1 | - | - | - | - | - | - | - | - | - | Команда JO передает управление по метке short-label, если признак переполнения OF установлен (т.е. =1). Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Пользуйтесь командой JNO, переход если нет переполнения, для перехода в том случае, когда признак переполнения OF сброшен (т.е. =0). |
JP short-label | Jump if PF = 1 | - | - | - | - | - | - | - | - | - | Команда JP передает управление по метке short-label, если признак четности PF установлен (т.е. =1). Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. |
JPE short-label | - | - | - | - | - | - | - | - | - | JPE - синоним JP. См. описание JP | |
JPO short-label | - | - | - | - | - | - | - | - | - | JPO - синоним JNP. См. описание JNP | |
JS short-label | Jump if SF = 1 | - | - | - | - | - | - | - | - | - | Команда JS передает управление по метке short-label, если признак знака SF установлен (т.е. =1). Цель перехода должна лежать в пределах от -128 до 127 байтов от следующей команды. Пользуйтесь командой JNS, переход если положительный результат, для перехода в том случае, когда признак знака SF сброшен (т.е. =0). |
JZ short-label | - | - | - | - | - | - | - | - | - | JZ - синоним JE. См. описание JE | |
LOOP short-label | CX Ü CX - 1 if (CX <> 0) JMP short-label | - | - | - | - | - | - | - | - | - | Команда LOOP уменьшает CX на 1, затем передает управление по метке short-label, если CX не равно 0. Операнд short-label должен находиться в пределах от -128 до +127 байтов от следующей команды. |
LOOPE short-label | CX Ü CX - 1 if (CX <> 0) and (ZF = 1) JMP short-label. | - | - | - | - | - | - | - | - | - | Команда LOOPE используется после команд CMP или SUB. Она уменьшает CX на 1, затем передает управление по метке short-label, если CX не равно нулю и если первый операнд команд CMP или SUB был равен второму операнду. Операнд short-label должен находиться в пределах от -128 до +127 байтов от следующей команды. Команда LOOPZ, переход пока ноль, - это та же команда, что и LOOPE. |
LOOPNE short-label | CX Ü CX - 1 if (CX <> 0) and (ZF = 0) JMP short-label. | - | - | - | - | - | - | - | - | - | Команда LOOPNE используется после команд CMP или SUB. Она уменьшает CX на 1, затем передает управление по метке short-label, если CX не равно нулю и если первый операнд команд CMP или SUB не равен второму операнду. Операнд short-label должен находиться в пределах от -128 до +127 байтов от следующей команды. Команда LOOPNZ, переход пока не ноль, - это та же команда, что и LOOPNE. |
: LOOPNZ short-label | - | - | - | - | - | - | - | - | - | LOOPNZ - синоним LOOPNE. См. описание LOOPNE | |
: LOOPZ short-label | - | - | - | - | - | - | - | - | - | LOOPZ - синоним LOOPE. См. описание LOOPE | |
Прерывания | |||||||||||
INT interrupt-num | PUSHF TF Ü 0 IF Ü 0 CALL FAR (INT*4) | - | - | - | - | - | - | - | Команда INT загружает регистр FLAGS в стек, сбрасывает признаки трассировки и разрешения прерывания, загружает CS и IP в стек, затем передает управление обработчику прерываний, который определяется по значению операнда interrupt-num. Если обработчик прерываний производит возврат по команде IRET, то исходное значение регистра FLAGS восстанавливается. Регистр FLAGS хранится в том же формате, который используется в команде PUSHF. Адрес вектора прерывания определяется умножением операнда interrupt-num на 4. Первое слово, находящееся по полученному адресу, загружается в IP, а второе слово - в CS. Все номера interrupt-num, кроме типа 3, вырабатывают двухбайтовый код операции; interrupt-num, равный 3, вырабатывает однобайтовую команду, называемую прерыванием по контрольной точке (Breakpoint interrupt). | ||
INTO | if (OF = 1) PUSHF TF Ü 0 IF Ü 0 CALL FAR (10h) | - | - | - | - | - | - | - | Команда INTO активизирует прерывание типа 4, если признак переполнения OF равен 1; если OF = 0, то эта команда не выполняет никаких действий. Если OF = 1, то прерывание выполняется аналогично команде INT 4; | ||
IRET | POP IP POP CS POPF | * | * | * | * | * | * | * | * | * | Команда IRET передает управление из подрограммы обработки прерываний в место возникновения прерывания, восстанавливая из стека значения регистров IP, CS и FLAGS |
Управление состоянием процессора | |||||||||||
CLC | CF Ü 0 | - | - | - | - | - | - | - | - | CLC сбрасывает признак переноса. Другие признаки не меняются | |
CLD | DF Ü 0 | - | - | - | - | - | - | - | - | CLD сбрасывает (устанавливает равным нулю) признак направления. Другие признаки не меняются. Сброшенный признак направления влечет увеличение SI и DI на единицу в командах обработки строк. | |
CLI | IF Ü 0 | - | - | - | - | - | - | - | - | CLI сбрасывает (устанавливает равным нулю) признак разрешения прерывания, вследствие чего процессор не распознает замаскированные прерывания. Другие признаки не меняются. (Немаскированные прерывания распознаются процессором всегда, независимо от значения признака IF.) | |
CMC | CF Ü NOT CF | - | - | - | - | - | - | - |