Пример 1

repe cmpsb ;Поиск различия в строках
je equal ;Переход, если строки
;совпадают
notequ: ;Продолжение, если строки
;не совпадают

В примере 1 строки не совпадают, и команда je выполнена не будет. После завершения сравнения строк управление будет передано на метку notequ. Содержимое регистров в этой точке: СХ=1 (так как не выполнено сравнение одной последней пары символов), SI = <смещение strl> + 7, DI = <смещение strl> + 7 (выполнено сравнение 7 пар символов).

Пример 2


;В полях данных сегмента данных, адресуемого через DS:
strl db '12345678*90' ;1-я строка
;В полях данных сегмента данных, адресуемого через ES:
str2 db ' abcdefgh*ij' ;2-я строка
; В программном сегменте:
cld ;Сравнение вперед
mov SI,offset strl;DS:SI ' strl
mov DI,offset str2;ES:DI ' str2
mov CX,11 ;Длина сравниваемых строк
repne cmpsb ;Поиск первой пары
;одинаковых элементов
jne notequ ;Переход, если таковой нет
found: ;Продолжение, если пара
;одинаковых элементов найдена
В примере 2 имеется пара одинаковых элементов (*) в позиции 8 от начата строк. Поэтому команда jne выполнена не будет. После завершения сравнения строк управление будет передано на метку found. Содержимое регистров в этой точке: СХ=2 (так как не выполнено сравнение двух последних пар символов), SI = <смещение strl> + 9, DI = <смешенис strl> + 9 (выполнено сравнение 9 пар символов).

Пример 3

В полях данных сегмента, адресуемого через ES:
strl db '09.12.1998' ;1-я строка
str2 db '09.12.1998' ;2-я строка
;В программном сегменте:
eld ;Сравнение вперед
mov SI, off set strl ;DS:SI -> strl
mov DI,offset str2 ;ES:DI -> str2
mov CX,10 ;Длина сравниваемых строк
repe cmps ES:str1,ES:str2 ;Поиск различия в строках
je equal ; Переход, если строки
;одинаковы
notequal: ;Продолжение, строки
;различаются

В примере 3 строки одинаковы и после завершения сравнения управление будет передано на метку equal. Поскольку строки описаны с помощью директив db, фактически выполняется команда cmpsb, т.е. побайто вое сравнение.

Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров.

386+ CMPSD Сравнение строк по двойным словам


Команда аналогична командам МП 86 cmpsb и cmpsw, но позволяет сравнивать 32-битовые участки строк, адресуемых через регистры DS:ESI и ES:EDI (или, в 16-разрядных приложениях, через DS:SI и ES:DI). Использование мнемоники cinpsd с префиксом rep не означает, что в качестве счетчика будет автоматически использоваться расширенный регистр ЕСХ.

Пример


В полях данных сегмента, адресуемого через DS
areal dd 152345,168666,954333
area2 dd 152345,168666,954331
;B программном сегменте
push DS
pop ES ;ES=DS
mov SI,offset areal ;DS:SI ->areal
mov DI,offset area2 ;ES:DI ->area2
mov CX,3 ;Будем сравнивать З числа
repe cmpsd
je equal
В приведенном примере в строках (фактически это целочисленные массивы) различаются последние элементы, и команды jc выполнена не будет. 

 
486+ CMPXCHG Сравнение и обмен

Команда cmpxchg выполняет в одной операции сравнение и обмен операндов. Команда требует два параметра и неявным образом использует третий операнд - регистр ЕАХ. Первый операнд (приемник) должен находиться в 16- или 32-битовой ячейке памяти, второй операнд (источник) - в регистре общего назначения такого же размера. Команда выполняет сравнение операнда-приемника с содержимым неявного операнда - регистра ЕАХ. Если сравниваемые значения совпадают, операнд-приемник замещается операндом-источником (т.е. содержимое регистра записывается в память). Если сравниваемые значения не совпадают, содержимое памяти (приемник) поступает в регистр ЕАХ. Команда воздействует на флаги OF, SF, ZF, AF, PF и CF.

Пример 1


; В полях данных
mem dw 135
; В программном сегменте
mov AX,135
mov BX,60
cmpxchg mem,BX ;mem=AX. Регистр ® память ;
mem=60, BX=60, АХ=135

Пример 2


; В полях данных
mem dw 135
;В программном сегменте
mov AX,148
mov BX,60
cmpxchg mem,BX ;mem<>AX. Память ® АХ
;mem=135, BX=60, AX=148

 
Pentium+ CMPXCHG8B Сравнение и обмен 8 байтов


Команда cmpxchgSb выполняет в одной операции сравнение и обмен 8-байтовых операндов. Команда требует один параметр и неявным образом использует еще два операнда - пары регистров EDX:EAX и ЕСХ:ЕВХ. В качестве явного операнда команды (приемника) может выступать только 64-битная (8-байтовая) ячейка памяти. Команда выполняет сравнение операнда-приемника в памяти с содержимым EDX:EAX. Если сравниваемые значения совпадают, то операнд-приемник в памяти замещается 64-битным значением ЕСХ:ЕВХ. Если сравниваемые значения не совпадают, содержимое памяти поступает в пару регистров EDXrEAX, замещая один из сравниваемых операндов. Команда воздействует на флаг ZF.

Пример 1


; В полях данных
mem dq 1122334455667788h
;В программном сегменте
mov ЕСХ,9
mov ЕВХ,5
mov EDX,11223344h
mov EAX,55667788h
cmpxchgSb mem ;mem=EDX:EAX. ECX:EBX ® mem ;
mem=0000000900000005h

Пример 2


; В полях данных
mem dq 1122334455667788h
;B программном сегменте
mov ECX,9
mov EBX,5
mov EDX,11223344h
mov EAX,55667789h
cmpxchgSb mem ;memOEDX: EAX. Mem -" EDX : EAX ;mem=1122334455667788h ;EDX=11223344h, EAX=55667788h
При работе с многобайтовыми данными не следует забывать о том, что в памяти байты любых данных всегда выстраиваются в порядке их номеров, т.е. от младшим к все более старшим, в то время как при изображении чисел мы применяем обратный порядок - сначала пишем старшие разряды числа, затем младшие. В то же время символьные строки мы изображаем так же, как они располагаются в памяти - для нас естественно считать, что по мере движения по строке вправо номер символа возрастает.

Пример 3


; В полях данных
meml db '12345678' ;Строка-операнд
mem2 db '12345678' ;Сравниваемая строка
;В программном сегменте
mov ECX,68676665h ;'efgh'
mov EBX,64636261h ;'abcd'
mov EDX,dword ptr mem2+4 ;Забираем старшую
;часть строки
mov EAX,dword ptr mem2 ;Забираем младшую
;часть строки
cmpxchg8b gword ptr meml ;Операнды совпадают
;ZF=1, mem1=''abcdefgh''
;ECX:EBX без изменений
;EDX:EAX без изменений
 

Пример 4


;В полях данных
meml db '12345678' ;Строка-операнд
mem2 db 'abcdefgh' ;Сравниваемая строка
; В программном сегменте
mov ECX,68676665h ;'efgh'
mov EBX,64636261h ;'abed'
mov EDX,dword ptr mem2+4 ;3абираем старшую
;часть строки
mov EAX,dword ptr mem2 ;Забираем младшую
;часть строки
cmpxchg8b qword ptm mem1 ;Операнды не совпадают
;ZF=0, EDX=38373635='5678'
;EAX=34333231='1234'
;mem1s без изменения
;При неравенстве ЕСХ:ЕВХ не принимают участие в операции
 
Pentium+ CPUID Идентификация процессора

Команда cpuid позволяет получить код идентификации процессора, установленного на данном компьютере. Команда в качестве неявного операнда использует регистр ЕАХ. Для процессоров Pentium регистр ЕАХ перед вызовом команды cpuid может принимать два значения: 0 и 1. Если ЕАХ=0, то команда возвращает в регистре ЕАХ код 1, а в регистрах ЕВХ, EDX и ЕСХ (именно в таком порядке) - три части символьной строки, идентифицирующей изготовителя процессора. Для процессоров Intel возвращаемая строка в целом имеет вид "Genumclatcl".
Если перед вызовом команды cpuid значение ЕАХ равно 1, то команда возвращает в регистре ЕАХ коды разработки конкретной версии процессора, а в регистре EDX код IBFli, содержащий информацию о возможностях процессора.
Коды разработки в регистре ЕАХ хранятся в следующем формате:

биты 0 ... 3 - номер поколения (например, 3);
биты 4 ... 7 - модель (например, 4);
биты 8 ... 11 - семейство (5 для Pentium).

Содержимое регистра EDX включает конфиденциальную информацию изготовителя, а также говорит о наличии на кристалле микропроцессора арифметического сопроцессора (бит 0) и поддержке команды cmpxchgSb (бит 8).

Пример


;В полях данных mem dd 0,0,0 ;В программном сегменте
mov ЕАХ,О
cpuid ;EAX=0001h
mov mem, ЕВХ
mov mem+4, EDX
mov mem+8, ECX ;mem='Genuinelntel'
cpuid EAX=543h (например) ,EDX = lBFh

CWD Преобразование слова в двойное слово

Команда cwd заполняет регистр DX знаковым битом содержимого регистра АХ, преобразуя тем самым 16-разрядное число со знаком в 32-разрядное, размещаемое в регистрах DX:AX. Команду удобно использовать для преобразования двухбайтового делимого в четырехбайтовое (двойное слово) при делении на 16-разрядный операнд. Команда не имеет параметров и не воздействует на флаги процессора.

Пример 1


mov AX,32767 ;AX=7FFFh
cwd ;AX=7FFFh, DX=OOOOh.
;DX:AX=32767

Пример 2


mov AX,-32768 ;AX=8000h
cwd ;AX=8000h, DX=FFFFh.
;DX:AX=-32768

386+ CWDE Преобразование слова в двойное слово с расширением

Команда cwde заполняет старшую половину регистра ЕАХ знаковым битом содержимого регистра АХ, преобразуя тем самым 16-разрядное число со знаком в 32-разрядное, размещаемое в расширенном регистре ЕАХ. Команда не имеет операндов и не воздействует на флаги процессора.
Пример

; В полях данных
mem dw - 3
;В программном сегменте
mov AX,mem ;AX=FFFD
cwde ;EAX=FFFFFFFDh
 
DAA Десятичная коррекция в регистре AL после сложения
Команда daa корректирует результат сложения в регистре AL двух упакованных двоично-десятичных (BCD) чисел (по одной цифре в каждом полубайте), чтобы получить пару правильных упакованных двоично-десятичных цифр. Команда используется вслед за операцией сложения упакованных двоично-десятичных чисел. Если результат сложения превышает 99, возникает перенос и устанавливается флаг CF. Команда воздействует на флаги SF, ZF, AF, PF и CF.
Пример 1

mov AL,87h ;Упакованное BCD 87
add AL,04h ;После сложения AL=8Bh
daa ;AL=91h, т.е. упакованное BCD 91
Пример 2

mov AL,87h ;Упакованное BCD 87
add AL,11h ;После сложения AL=97h
daa ;AL=97h, т.е. упакованное
;BCD 97 (в данном случае
;команда daa ничего не делает)

DAS Десятичная коррекция в регистре AL после вычитания

Команда das корректирует результат вычитания в регистре AL двух упакованных двоично-десятичных (BCD) чисел (по одной цифре в каждом полубайте), чтобы получить пару правильных упакованных десятичных цифр. Команда используется вслед за операцией вычитания упакованных двоично-десятичных чисел. Если для вычитания требовался заем, устанавливается флаг CF. Команда воздействует на флаги SF, ZF, AF, PF и CF.
Пример 1

mov AL,55h ;Упакованное BCD 55
sub AL,19h ;После вычитания AL=3Ch
das ;AL=36h, т.е. упакованное BCD 36
Пример 2

mov AL,55h ;Упакованное BCD 55
sub AL,15h ;После вычитания AL=40h
das ;AL=40h, т.е. упакованное
;BCD 40 (в данном случае
;команда das ничего не делает)

DEC Декремент (уменьшение на 1)

Команда dec вычитает 1 из операнда, в качестве которого можно указывать регистр (кроме сегментного) или ячейку памяти размером как в байт, так и в слово. Не допускается использовать в качестве операнда непосредственное значение. Операнд интерпретируется как число без знака. Команда воздействует на флаги OF, SF, ZF, AF и PF.
Пример 1

mov AX,0FFFFh
dec AX ;AX=FFFEh
Пример 2

mov CX,0
dec CX ;CX=FFFFh
Пример 3

mov CX,3500h
dec CL ;CX=35FFh
Пример 4

; В полях данных
mem dw 68
;B программном сегменте
dec mem mem=67
Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров.
Пример

mov EAX, 0
dec EAX ;EAX=FFFFFFFFh

DIV Деление целых чисел без знака

Команда div выполняет деление целого числа без знака, находящегося в регистрах АХ (в случае деления на байт) или DX:AX (в случае деления на слово), на операнд-источник (целое число без знака). Размер делимого в два раза больше размеров делителя и остатка.
Для однобайтовых операций делимое помещается в регистр АХ; после выполнения операции частное записывается в регистр AL, остаток - в регистр АН.
Для двухбайтовых операций делимое помещается в регистры DX:AX (в DX - старшая часть, в АХ - младшая); после выполнения операции частное записывается в регистр АХ, остаток - в регистр DX.
В качестве операнда-делителя команды div можно указывать регистр (кроме сегментного) или ячейку памяти; не допускается деление на непосредственное значение. Если делитель равен 0, или если частное не помещается в назначенный регистр, возбуждается прерывание с вектором 0. Команда не воздействует на флаги процессора.
Команду div можно использовать для целочисленного деления неупакованного двоично-десятичного числа в регистре АХ не неупакованный двоично-десятичный делитель, если перед ней выполнить команду aad (см. пример 3).
Пример 1

mov AX,506 ;Делимое
mov BL,50 ;Делитель
div BL ;AL=0Ah (частное), AH=06h (остаток)
Пример 2

; В полях данных
long dd 65537 ;Делимое
;В программном сегменте
mov DX,word ptr long+2 ;DX=0001h, старшая
;часть делимого
mov AX,word ptr long ;AX=0001h, младшая
;часть делимого
mov CX,256 ;Делитель
div CX ;AX=0100h (частное),
;DX=0001h (остаток)
Пример З

mov AX,0807h ;Неупакованное BCD 87
mov DL,09h ;Неупакованное BCD 9
aad ;AX=0057h=87
div DL ;AX=0609h, т.е. 9 и 6 в остатке
Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. При этом, если делитель представляет 32-битовую величину, то возможен только один вариант команды деления, когда делимое находится в парс регистров EDX:EAX. В этом случае частное будет помещено в регистр ЕАХ, остаток - в EDX.
Пример

mov ЕАХ, 0FFFFFFFh ;Младшая часть делимого
mov EDX,0 ;Старшая часть делимого
mov EBX,256 ;Делитель
div EBX ;Частное в EAX=000FFFFFh,
;Остаток в EDX=000000FFh

386+ ENTER Создание стекового кадра для параметров процедуры

Команда enter, обычно являющаяся первой командой процедуры, выделяет заданный объем стекового пространства для локальных (автоматических) параметров процедуры, предоставляя процедуре указатель на выделенную область (в качестве такого указателя используется регистр ЕВР) и смещая указатель стека ESP так, чтобы он указывал на начало свободного стекового пространства. В результате процедура имеет возможность обращаться по ходу своего выполнения к своим локальным параметрам и, в то же время, пользоваться оставшимся пространством стека для временного сохранения в нем любых данных с помощью команд push и pop. Команда leave в конце процедуры выполняет обратные действия, возвращая стек в исходное состояние и уничтожая область локальных переменных. Локальными, как известно, называются как раз те переменные, которые существуют только в течение времени выполнения некоторой процедуры, и автоматически исчезают после се завершения.
Команды enter и leave используются многими языками высокого уровня для управления доступом к локальным переменным вложенных процедур.
Команда enter имеет два операнда. Первый (16-битовое непосредственное значение) определяет число байтов, выделяемых в стеке для локальных переменных. Для 32-разрядных приложений место в стеке выделяется двойными словами (по 4 байт), для 16-разрядных - словами (по 2 байт). Второй операнд (8-битовос непосредственное значение) задаст так называемый лексический уровень процедуры, характеризующий степень ее вложенности. В зависимости от значения лексического уровня, команда enter выполняется по-разному. При лексическом уровне, равном 0, реализуется невложенная форма команды enter. В этом случае после входа в процедуру (командой call) с сохранением в стеке адреса возврата, в стек заносится текущее содержимое регистра ЕВР, в ЕВР копируется текущее значение указателя стека, а указатель стека смещается на число байтов, заданное первым операндом команды enter . Создаваемая на сте-ке структура носит название стекового кадра, а регистр ЕВР выполняет в данном случае функцию указателя стекового кадра.
Подпрограмма имеет возможность обращаться к своим локальным переменным по адресам ESP-4 и ESP-8 (для случая резервирования места под две переменные). Занеся в стек по этим адресам некоторые данные (полученные в качестве параметров вызова через регистры общего назначения или созданные самостоятельно) подпрограмма может затем многократно к ним обращаться, не боясь их затирания в процессе использования стека. Поскольку команда enter настроила указатель стека на область, находящуюся за пределами локальных переменных, программа может использовать команды push для сохранения в стеке временных данных.
Команда leave, размещаемая в самом конце процедуры, перед завершающей командой ret, копирует содержимое ЕВР в ESP, освобождая (в логическом плане) область локальных переменных, и снимает со стека сохраненное там исходное содержимое ЕВР. После этого командой ret можно вернуться в вызывающую процедуру.
Поскольку первый параметр команды enter имеет размерность слова, процедура в принципе имеет возможность зарезервировать в стеке для своих локальных переменных до 64 Кбайт стекового пространства.
Лексические уровни, отличные от 0, используются в тех случаях, когда по правилам языка высокого уровня каждая вложенная процедура имеет право обращаться к локальным переменным всех вышележащих процедур, но не к процедурам, находящимся на параллельных с ней ветвях вложенности. Другими словами, область видимости переменных распространяется на все вложенные процедуры, но две подпрограммы, вызываемые из одной и той же (вышележащей) процедуры, "не видят" друг друга.
В таких случаях главной процедуре назначается лексический уровень 1, все вызываемые из нее подпрограммы получают значение лексического уровня 2, подпрограммы, вызываемые из этих процедур, имеют уровень 3 и т.д. Команды enter при ненулевом значения второго параметра создают в стеке стековые кадры с более сложной структурой. Отличие такого стекового кадра от рассмотренного выше заключается в том, что в него, помимо области локальных переменных, входят также указатели стековых кадров всех вышележащих процедур. В результате любая подпрограмма может с помощью своего указателя (т.е. содержимого ESP) обратиться к собственных! переменным, а используя хранящиеся в стеке указатели кадров вышележащих процедур, "дотянуться" и до их локальных переменных. По-прежнему команды leave освобождают стек от стековых кадров вместе со всеми находящимися в них данными.
Пример

;Вызывающая процедура
call subrl
;Подпрограмма subrl
subrl proc
enter2048,0 ;Место под локальные данные
. . . ;Работа с локальными данными
leave
ret
 
HLT Останов
Команда hlt прекращает выполнение программы и переводит процессор в состояние останова. Работа процессора возобновляется после операции запуска, а также в случае прихода немаскируемого или разрешенного маскируемого прерываний.

IDIV Деление целых чисел со знаком

Команда IDIV выполняет деление целого числа со знаком, находящегося в регистрах АХ (в случае деления на байт) или DX:AX (в случае деления на слово), на операнд-источник (целое число со знаком). Размер делимого в два раза больше размеров делителя и остатка. Оба результата рассматриваются как числа со знаком, причем знак остатка равен знаку делимого.
Для однобайтовых операций делимое помещается в регистр АХ; после выполнения операции деления частное записывается в регистр AL, остаток - в регистр АН.
Для двухбайтовых операций делимое помещается в регистры DX:AX (в DX - старшая часть, в АХ - младшая); после выполнения операции деления частное записывается в регистр АХ, остаток - в регистр DX.
В качестве операнда-делителя команды idiv можно указывать регистр данных или ячейку памяти; не допускается деление на непосредственное значение. Если делитель равен 0, или если частное не помещается в назначенный регистр, возбуждается прерывание через вектор 0. Команда не воздействует на флаги процессора.
Пример 1

mov AX,506 ;Делимое
mov BL,50 ;Делитель
idiv BL ;AL=0Ah (частное), AH=06h
; (остаток)
Пример 2

;В полях данных
long dd 0F0007h ;Делимое
; В программном сегменте
mov DX,word ptr long+2;DX=000Fh, старшая
;часть делимого
mov AX,word ptr long;AX=0007h, младшая
;часть делимого
mov CX,256 ;Делитель
idiv СХ ;AX=0F00h (частное),
;DX=0007h (остаток)
Пример 3
mov AX,-506 ;AX=FE06h, делимое
mov BL,50 ;Делитель
idiv BL ;AL=F6h (-10), AH=FAh (-6)
Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. При этом, если делитель представляет 32-битовую величину, то возможен только один вариант команды деления, когда делимое находится в парс регистров EDX:EAX. В этом случае частное будет помещено в регистр БАХ, остаток - в EDX.
Пример

; В полях данных
dvd dq -100001 Делимое
;B программном сегменте
mov EAX,dword ptr dvd EAX=FFFE795Fh
;(младшая часть делимого)
mov EDX,dword ptr dvd+4 EDX=FFFFFFFFh (старшая
;часть делимого)
mov EBX,50 Делитель
idiv EBX Частное в EAX=FFFFF830h=
;-2000, остаток в EDX=FFFFFFFFh=-1

IMUL Умножение целых чисел со знаком

Команда IMUL выполняет умножение целого числа со знаком, находящегося в регистре AL (в случае умножения на байт) или АХ (в случае умножения на слово), на операнд-источник (целое число со знаком). Размер произведения в два раза больше размера сомножителей.
Для однобайтовых операций один из сомножителей помещается в регистр AL; после выполнения операции произведение записывается в регистр АХ.
Для двухбайтовых операций один из сомножителей помещается в регистр АХ; после выполнения операции произведение записывается в регистры DX:AX (в DX - старшая часть, в АХ - младшая).
В качестве операнда-сомножителя команды imul можно указывать регистр (кроме сегментного) или ячейку памяти; не допускается умножение на непосредственное значение. Команда воздействует на флаги OF и CF. Если АН или DX представляют собой просто знаковое расширение AL или АХ, соответственно (т.е. результат умножения со знаком верен), OF и CF сбрасываются в 0; в противном случае (результат со знаком не помещается в АХ или DX:AX) OF и CF устанавливаются в 1.
Пример 1

mov AL,5 ;Первый сомножитель
mov BL,3 ;Второй сомножитель
imul BL ;AX=000Fh (произведение)
Пример 2

mov AX,256 ;Первый сомножитель
mov BX,256 ;Второй сомножитель
imul BX ;DX=0001h, AX=0000h
;(число 65536)
Пример 3

mov AL,-5 ;AL=FBh
mov BL,3 ;BL=03h
imul BL ;AX-'FFF1h (-15)
Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров. Имеются также варианты команды с двумя и тремя операндами.

Для команды imul с одним операндом второй сомножитель должен располагаться в AL, АХ или ЕАХ. Процессор выбирает размерность второго сомножителя, исходя из размерности первого, указанного в качестве операнда. 16-, 32- или 64-битовый знаковый результат помещается в регистры АХ, DX:AX или EDX:EAX, соответственно. Если после операции умножения содержимое АН, DX или EDX является лишь знаковым расширением AL, АХ или ЕАХ, соответственно, то флаги CF и OF сбрасываются в 0. В противном случае они устанавливаются в 1.
Для команды imul с двумя операндами их произведение записывается в первый операнд; второй операнд не изменяется. В качестве первого операнда могут выступать 16- или 32-разрядные регистры общего назначения; в качестве второго операнда - 16- или 32-разрядные регистры общего назначения, 16- или 32-битовые ячейки памяти или непосредственное значение. Оба операнда должны иметь один размер. Если результат умножения помещается в первый операнд, флаги CF и OF сбрасываются в 0. В противном случае они устанавливаются в 1.
Для команды imul с тремя операндами произведение второго и третьего операндов записывается в первый операнд. В качестве первого операнда могут выступать 16- или 32-разрядные регистры общего назначения; в качестве второго операнда - 16- или 32-разрядные регистры общего назначения или 16- или 32-битовые ячейки памяти; в качестве третьего операнда - только непосредственное значение. Два первых операнда должны иметь один размер. Если результат умножения помещается в первый операнд, флаги CF и OF сбрасываются в 0. В противном случае они устанавливаются в 1.
Пример 1

mov EAX,-1 ;Первый сомножитель
mov ESI,100000000 ;Второй сомножитель
imul ESI ;EDX=FFFFFFFFh,
;EAX=FA0AlF00h
;Результат=-100000000
Пример 2

;В полях данных
ор2 dd 100h ;Первый сомножитель
; В программном сегменте
mov EAX,400000h ;Второй сомножитель
imul EAX,op2 ;EAX=40000000h
Пример 3
mov BX,300h
imul АХ,ВХ,4 ;AX=300h*4=0C00h

IN Ввод из порта

Команда in вводит в регистр AL или АХ соответственно байт или слово из порта, указываемого вторым операндом. Адрес порта помещается в регистр DX. Если адрес порта не превышает 255, он может быть указан непосредственным значением. Указание регистра-приемника (AL или АХ) обязательно, хотя с другими регистрами команда in не работает, и их указывать нельзя. Команда не воздействует на флаги процессора.
Пример 1

in AL, 60h ;Ввод байта из порта 60h
Пример 2

mov DX,3D5h ;Адрес порта
in AL,DX ;Ввод байта из порта 3D5h
Допустимо использование в качестве операнда-приемника расширенного регистра ЕАХ (если адресуемое устройство позволяет прочитать из его порта двойное слово).
Пример

mov DX,345h ;Адрес порта
in EAX,DX

INC Инкремент (увеличение на 1)

Команда inc прибавляет 1 к операнду, в качестве которого можно указывать регистр (кроме сегментного) или ячейку памяти размером как в байт, так и в слово. Не допускается использовать в качестве операнда непосредственное значение. Операнд интерпретируется как число без знака. Команда воздействует на флаги OF, SF, ZF, AF и PF. Команда не воздействует на флаг CF; если требуется воздействие на этот флаг, необходимо использовать команду add op,l.

Пример 1

mov AX,0563h
inc AX ;AX=0564h
Пример 2

mov BH,15h
inc BH ;BH=16h
Пример 3

mov AX,A5FFh
inc AL ;AX=A500h
inc AH ;AX=A600h
Пример 4

mov AX,0FFFFh
inc AX ;AX=0000h, ZF=1, CF=0
;Для сравнения:
mov CX,0FFFFh
add CX,1 ;CX=0000h, ZF=1, CF=1
Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров.
Пример

;В полях данных
mem dd 12345678h
; В программном сегменте
inc mem ;mem=12345679h
 
INS Ввод строки из порта
INSB Ввод байта из порта
INSW Ввод слова из порта
INSD Ввод двойного слова из порта

Команды предназначены для ввода данных из порта непосредственно в память. Адрес порта указывается, как и для команды in, в регистре DX, при этом задание адреса порта непосредственным значением не допускается. Данные пересылаются по адресу, находящемуся в паре регистров ES:EDI. Замена сегмента не допускается. Команда insb переносит из порта 1 байт, команда insw - 1 слово, команда insd - 1 двойное слово, а команда ins может быть использована для передачи байтов, слов и двойных слов. В последнем случае размер загружаемого данного определяется описанием строки (с помощью директив db, dw или dd). После передачи данных регистр EDI получает положительное (если флаг DF=0) или отрицательное (если флаг DF=1) приращение. Величина приращения составляет 1, 2 или 4, в зависимости от размера передаваемых данных. Вариант команды ins имеет формат
ins строка, DX
(что не избавляет от необходимости инициализировать регистры ES:EDI адресом строки).
Если устройство, адресуемое через порт, может передавать последовательность данных, то команды ins можно предварить префиксом повторения rep. В этом случае из порта принимается СХ элементов данных заданного размера.
Команды ins не воздействуют на флаги процессора.
Пример

;В сегменте данных, адресуемых через DS
mem dw 0
;В программном сегменте
push DS
pop ES ;ES=DS
mov DI,offset mem;ES:DI -> mem
mov DX,303h ;Адрес порта
insw ;Ввод из порта 16-битового данного
 
INT Программное прерывание
Команда hit инициирует в процессоре процедуру прерывания, в результате которой управление передается на обработчик прерывания с номером n, который указан в качестве операнда команды int. В стек текущей программы заносится содержимое регистра флагов, сегментного регистра CS и указателя команд IP, после чего в регистры IP и CS передается содержимое двух слов из вектора прерывания с номером n (расположенных по адресам 0:n*4 и 0:n*4+2). Команда сбрасывает флаги IF и TF в 0. Команда iret, которой всегда завершается обработчик прерывания, восстанавливает исходное состояние этих флагов.
Пример 1

int 60h ;Переход на прикладной
;обработчик прерывания 60h
Пример 2

mov AH,1 ;Функция MS-DOS - ввод с
;клавиатуры кода ASCII символа
int 2h ;Вызов MS-DOS
Пример 3

mov АН, 0 ;Функция BIOS (прерывание
;16h) - ввод с клавиатуры
;кода ASCII и скен-кода символа
int 16h ;Вызов BIOS

INTO Прерывание по переполнению

Команда into, будучи установлена вслед за какой-либо арифметической, логической или строковой командой, вызывает обработчик прерываний через вектор 4, если предшествующая команда установила флаг переполнения OF. Перед использованием команды INTO прикладной программист должен поместить в вектор прерывания 4 двухсловный адрес своей программы обработки прерывания по переполнению. Команда сбрасывает флаги IF и TF в 0. Команда iret, которой всегда завершается обработчик прерывания, восстанавливает исходное состояние этих флагов.
Пример

add AX,BX ;Произвольная команда
into ;Вызов прикладного
;обработчика через вектор 4,
;если OF=1
... ;Продолжение программы, если OF=0

IRET Возврат из прерывания

Команда iret возвращает управление прерванному в результате аппаратного или программного прерывания процессу. Команда извлекает из стека три верхние слова и помещает их в регистры IP, CS и флагов (см. команду int). Командой iret должен завершаться любой обработчик прерываний, как аппаратных, так и программных (от команды int). Команда не воздействует на флаги, однако она загружает в регистр флагов из стека его исходное содержимое, которое было там сохранено процессором в процессе обслуживания прерывания. Если требуется, чтобы после возврата из обработчика программного прерывания командой iret какие-либо флаги процессора были установлены требуемым образом (весьма распространенный прием), их установку надо выполнить в копии флагов в стеке.

386+ IRETD


Возврат из прерывания в 32-разрядном режиме
Команда iretd используется в защищенном режиме для возврата из обработчика прерывания или исключения, а также для переключения на исходную задачу. В отличие от 16-разрядной команды iret, данная команда, завершая обработку прерывания или исключения, снимает со стека 3 двойных слова, содержащие расширенный регистр флагов EFALGS, CS и расширенный указатель команд EIP. В случае переключения задач команда iretd выполняет переключение контекстов задач - сохранение состояния завершающейся задачи в ее сегменте состояния задачи и загрузку регистров процессора из сегмента состояния исходной задачи.

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г. Яндекс.Метрика