Описание системы команд

микропроцессоров Intel

Материал, приведенный в данном разделе справочной системы, связан с уроком 6, на котором мы рассматривали формат машинной команды микропроцессора и систему его команд в целом.
Выберите тему:

Знакомство с порядком описания команд и принятыми обозначениями
Описание команд микропроцессора, упорядоченное по алфавиту
Описание команд микропроцессора, упорядоченное по функциональному признаку
 
 
 
 

aaa aad aam aas adc add and
bound bsf bsr bswap bt btc btr
bts call cbw cwde clc cld cli
cmc cmp cmps/cmpsb 
/cmpsw/cmpsd
cmpxchg cwd cdq daa
das dec div enter hlt idiv imul
in inc ins/insb 
/insw/insd
int into iret/iretd jcc
jcxz jecxz jmp lahf lds les lfs
lgs lss lea leave lgdt lidt lods/lodsb 
/lodsw/lodsd
loop loope loopz loopne loopnz mov movs/movsb 
/movsw/movsd
movsx movzx mul neg nop not or
out outs pop popa popad popf popfd
push pusha pushad pushf pushfd rcl rcr
rep/repe/repz 
/repne/repnz
ret/retf rol ror sahf sal sar
sbb scas/scasb 
/scasw/scasd
setcc sgdt sidt shl shld
shr shrd stc std sti stos/stosb 
/stosw/stosd
sub
test xadd xchg xlat/xlatb xor    
 
 
 
 

Порядок описания команд будет следующим:

 

Для описания команд приняты обозначения:

  1. Для описания состояния флагов после выполнения некоторой команды будем использовать выборку из таблицы, отражающей структуру регистра флагов eflags:
  2. 31 18 17 16 15 14 1312 11 10 09 08 07 06 05 04 03 02 01 00
    0 0 VM RF 0 NT IOPL OF DF IF TF SF ZF 0 AF 0 PF 1 CF
                                         
    В нижней строке этой таблицы приводятся значения флагов после выполнения команды. При этом используются следующие обозначения:
  3. Для представления операндов в синтаксических диаграммах используются следующие обозначения:
  4. На многих диаграммах в целях компактности возможные сочетания операндов показаны в виде следующей конструкции:
  5. Конструируя команду на основе подобной синтаксической диаграммы, вы должны помнить о соответствии типов. В подобной диаграмме допустимы только следующие сочетания: "r8, m8", "r16, m16", "r32, m32". Например, сочетание "r8, m16" недопустимо. Однако есть единичные случаи, когда подобные сочетания возможны; тогда они специально оговариваются.

  6. Описанная в данном приложении система команд в полном объеме поддерживается микропроцессором Pentium. Предыдущие модели микропроцессора могут не поддерживать отдельные команды. Чтобы прояснить этот момент, мы будем указывать в примерах для каждой команды директиву типа .286. Это будет означать, что описываемая команда поддерживается всеми моделями микропроцессора, начиная с i286. Если ничего не указывается, то это означает, что данная команда работает на всех моделях микропроцессоров Intel, начиная с i8086/8088.

AAA

(Ascii Adjust after Addition)
ASCII-коррекция после сложения
 
Схема команды:  aaa 
Назначение: корректировка неупакованного результата сложения двух одноразрядных неупакованных BCD-чисел.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
? r ? r
Применение:
Обычно команда aaa используется после сложения каждого разряда распакованных BCD-чисел командой add. Каждая цифра неупакованного BCD-числа занимает младший полубайт байта. Если результат сложения двух одноразрядных BCD-чисел больше 9, то число в младшем полубайте результата не есть BCD-число. Поэтому результат нужно корректировать командой aaa. Эта команда позволяет сформировать правильное BCD-число в младшем полубайте и запомнить единицу переноса в старший разряд путем увеличения содержимого регистра ah на 1.
К примеру, сложить два неупакованных BCD-числа: 08 + 05:
        mov     ah,08h  ;ah=08h
        mov     al,05h  ;al=05h
        add     al,ah   ;al=al+ah=05h+08h=0dh — не BCD-число
        xor     ah,ah   ;ah=0
        aaa             ;ah=01h,al=03h — результат скорректирован
        
См. также: урок 8, приложение 7 и команды aad, aam, aas, daa, das

AAD

(Ascii Adjust before Division)
ASCII-коррекция перед делением
 
Схема команды:  aad 
Назначение: Синтаксис
Алгоритм работы: Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
? ?
Применение:
Команду aad используют для подготовки двузначного неупакованного BCD-числа в регистре ax для операции деления. Так как в системе команд микропроцессора нет команды деления для BCD-чисел, такое число нужно предварительно преобразовать в двоичный вид. Для этого старший разряд двузначного BCD-числа помещается в регистр ah, умножается на 10 и складывается с разрядом единиц двузначного BCD-числа 9 в регистре al. В результате этих действий и получается соответствующее двоичное число в регистре ax. Далее в программе уже можно применять обычную команду деления div, оперирующую двоичными данными. Команду aad можно применять и просто для преобразования неупакованного двузначного BCD-числа в его двоичный эквивалент. Есть еще интересный момент — если посмотреть на коды символов шестнадцатеричных цифр в таблице ASCII, то видно, что они похожи на BCD-числа. Исключение составляет лишь значение старшей тетрады (для BCD-числа это так называемая зона с нулевым значением) - оно равно 3. Можно сделать вывод, что если предварительно обнулить значение старшей тетрады для кодов двух символов (от 0 до 9), то эту команду вполне можно применять и для преобразования двузначных десятичных чисел в символьном представлении в их двоичный эквивалент, что и отражено в названии команды. Для иллюстрации рассмотрим два примера.

Пример 1. Разделить десятичное число 18 на 9. Подготовить результат к выводу на экран.
        mov     ah,01h  ;ah=01h
        mov     al,08h  ;al=08h => ax=0108h
        mov     bl,09   ;bl=09h
        aаd             ;al=12h — двоичный эквивалент десятичного числа 18
        div     bl      ;al=02h,ah=00h
        ог      al,30h  ;al=32h — ASCII-представление числа 2, можно выводить на экран
        
Пример 2. Преобразовать десятичное число 16 в символьном виде в эквивалентное двоичное число.
        mov     ax,3136h        ;ax=3136h
        and     ax,0f0fh        ;ax=0106h
        aаd             ;al=10h — получили его двоичный эквивалент
        
См. также: уроки 3, 8, приложение 7 и команды aaa, aam, aas, daa, das

AAM

(Ascii Adjust after Multiply)
ASCII-коррекция после умножения
 
Схема команды: aam
Назначение: Синтаксис
Алгоритм работы: Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
? ?
Применение:
Команду aam используют для коррекции результата умножения двух неупакованных BCD-чисел. Специальной команды умножения BCD-чисел нет. Поэтому BCD-числа умножаются поразрядно, как обычные двоичные числа, командой mul. Максимальное число, которое получается при таком умножении, — это 9*9=8110=5116. Отсюда понятно, что значения, для которых командой aam можно получить их двузначный BCD-эквивалент в регистре ax, находятся в дипазоне от 00h до 51h. Эту команду можно применять и для преобразования двоичного числа из регистра ax (в диапазоне от 0 до 63h) в его десятичный эквивалент(соответственно, из диапазона от 0 до 9910).

Пример 1. Умножить десятичное число 8 на 9. Подготовить результат к выводу на экран.
        mov     ah,08h  ;ah=08h
        mov     al,09h  ;al= 09h
        mul     ah      ;al=48h — двоичный эквивалент 72
        aam             ;ah=07h,al=02h
        or      ax,3030h        ;ax=3732h — ASCII-представление числа 72
Пример 2. Преобразовать двоичное число 60h в эквивалентное десятичное число.
;поместим число 60h в регистр ax
        mov     ax,60h  ;ax=60h
        aаm             ;ax=0906h — получили десятичный эквивалент числа 60h
        or      ax,3030h        ;символьный эквивалент, можно выводить на экран
См. также: урок 8, приложение 7 и команды aaa, aad, aas, daa, das

AAS

(Ascii Adjust after Substraction)
ASCII-коррекция после вычитания
 
Схема команды:  aas 
Назначение: корректировка результата вычитания двух неупакованных одноразрядных BCD-чисел.

Синтаксис
Алгоритм работы:
если (младший полубайт регистра al меньше 9) или (флаг af=1), то выполнить следующие действия:

иначе установить флаги af и cf в 1.

Состояние флагов после выполнения команды:

11 07 06 04 02 00
OF SF ZF AF PF CF
? r r
Применение:
Команду aas используют для коррекции результата вычитания двух неупакованных одноразрядных BCD-чисел после команды sub. Операндами в команде sub должны быть правильные одноразрядные BCD-числа. Рассмотрим возможные варианты вычитания одноразрядных BCD-чисел: Пример 1. Вычесть десятичное число 8 из 5. Подготовить результат к выводу на экран.
        mov     al,05h
        mov     bl,08h
        sub     al,bl   ;al=0fdh
        aas             ;al=07, cf=af=1
        or      al,30h  ;al=37h — код символа 7
;вывод результата на экран
        mov     ah,2
        mov     dl,al
        int     21h
        
См. также: уроки 3, 8, приложение 7 и команды aaa, aad, aam, daa, das

ADC

(Addition with Carry)
Сложение с переносом
 
Схема команды:  adc приемник,источник 
Назначение: сложение двух операндов с учетом переноса из младшего разряда.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
11 07 06 04 02 02
OF SF ZF AF PF CF
r r r r r
Применение:
Команда adc используется при сложении длинных двоичных чисел. Ее можно использовать как самостоятельно, так и совместно с командой add. При совместном использовании команды adc с командой add сложение младших байтов/слов/двойных слов осуществляется командой add, а уже старшие байты/слова/двойные слова складываются командой adc, учитывающей переносы из младших разрядов в старшие. Таким образом, команда adc значительно расширяет диапазон значений складываемых чисел. В приложении 7 приведен пример программы сложения двоичных чисел произвольной размерности.
.data
sl1     dd      01fe544fh
sl2     dd      005044cdh
elderREZ        db      0 ;для учета переноса из старшего разряда результата
rez     dd      0
.code
...
        mov     ax,sl1
        add     ax,sl2  ;сложение младших слов слагаемых
        mov     rez,ax
        mov     ax,sl+2
        adc     ax,sl2+2        ;сложение старших слов слагаемых плюс cf
        mov     rez+2,ax
        adc     elderREZ,0      ;учесть возможный перенос
        
См. также: урок 8, приложение 7 и команды add, sub, sbb, xadd

ADD

(ADDition)
Сложение
 
Схема команды:  add приемник,источник 
Назначение: сложение двух операндов источник и приемник размерностью байт, слово или двойное слово.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
r r r r r
Применение:
Команда add используется для сложения двух целочисленных операндов. Результат сложения помещается по адресу первого операнда. Если результат сложения выходит за границы операнда приемник (возникает переполнение), то учесть эту ситуацию следует путем анализа флага cf и последующего возможного применения команды adc. Например, сложим значения в регистре ax и области памяти ch. При сложении следует учесть возможность переполнения.
chiclo  dw      2015
rez     dd      0
...
        add     ax,chislo       ;(ax)=(ax)+ch
        mov     word ptr rez,ax
        jnc     dop_sum         ;переход, если результат не вышел за разрядную сетку
        adc     word ptr rez+2,0        ;расширить результат, для учета переноса
                                ;в старший разряд
dop_sum:
...
        
См. также: урок 8, Приложение 7 и команды adc, sub, sbb, xadd

AND

(logical AND)
Логическое И
 
Схема команды:  and приемник,источник 
Назначение: операция логического умножения для операндов приемник и источник размерностью байт, слово или двойное слово.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
11 07 06 02 00
OF SF ZF PF CF
0 r r 0
Применение:
Команда and используется для логического умножения двух операндов. Результат операции помещается по адресу первого операнда. Эту команду удобно использовать для принудительной установки или сброса определенных битов операнда.
Например, преобразуем двузначное упакованное BCD-число в его символьный эквивалент.
u_BCD   db      25h ;упакованное BCD-число
s_ch    dw      0 ;место для результата
...
        xor     ax,ax   ;очистка ax
        mov     al,u_BCD
        shl     ax,4    ;ax=0250
        mov     al,u_BCD        ;ax=0225
;преобразование в символьное представление:
        and     ax,3f3fh        ;ax=3235h
        mov     s_ch,ax
        
См. также: уроки 9, 12 и команды or, xor, test

BOUND

(check array BOUNDs)
Контроль нахождения индекса массива в границах
 
Схема команды:  bound индекс,границы массива 
Назначение: проверка нахождения значения индекса в границах массива.

Синтаксис
Алгоритм работы:
Cравнить значение в регистре индекс с двумя значениями, расположенными последовательно в ячейке памяти, адресуемой операндом границы массива. Диапазон значений индекса определяется используемым регистром индекс:

Если в результате проверки значение из регистра вышло за пределы указанного диапазона значений, то возбуждается прерывание с номером 5, если нет, программа продолжает выполнение.

Состояние флагов после выполнения команды:

выполнение команды не влияет на флаги
 
Применение:
Команду bound очень удобно использовать для контроля выхода за нижнюю или верхнюю границы массива. Значения этих границ должны быть предварительно помещены в два последовательных слова (двойных слова) в памяти. Адрес этих слов (двойных слов) указывается вторым операндом. Далее динамически в ходе работы программы значение в регистре индекс, указываемом первым операндом, сравнивается со значениями этих двух границ, и если нижняя_граница<=(индексindex)<=верхняя_граница, то программа продолжает выполнение. В противном случае генерируется исключительная ситуация 5 (int 5). Далее в программе обработки этой ситуации можно выполнить необходимую корректировку и вернуться в программу (см. урок 17).

Фрагмент, который можно использовать при обработке одномерного массива с размерностью элементов в слово:
.286    ;это обязательная директива, так как bound
        ;входит в систему команд микропроцессоров, начиная с i286
.data
BoundMas        label   word
Low_Bound       dw      0
Upp_Bound       dw      20
mas     dw      10 dup (?)
...
        xor     di,di   ;очистка индексного регистра
cycl:
        mov     ax,mas[di]      ;перебор
элементов массива
        add     di,2
        bound   di,BoundMas
;если значение в di не будет попадать в границы, то будет вызван
;обработчик прерывания 5, где можно скорректировать
;значение ip/eip в стеке с тем, чтобы выйти
;из бесконечного ;цикла, например, на метку М2 или
;выполнить другие действия
        jmp     cycl
М2:
...
        
См. также: урок 17 и команду iret/iretd

BSF

(Bit Scan Forward)
Побитное сканирование вперед
 
Схема команды:  bsf результат,источник 
Назначение: для проверки наличия единичных битов в операнде источник.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
06
ZF
r
Применение:
Команду bsf используют при работе на битном уровне для определения позиции в операнде крайних справа единичных битов.
Например, сдвинем содержимое регистра bx вправо таким образом, чтобы нулевой бит стал единичным:
.386
        mov     bx,0002h        ;bx=0000 0010b
...
        bsf     cx,bx   ;cx=0001h
        jz      null
        shr     bx,cl   ;bx=0000 0001b
...
null:
        
См. также: урок 9, 12 и команду bsr

BSR

(Bit Scan Reverse)
Побитное сканирование назад
 
Схема команды:  bsr результат,источник 
Назначение: проверка наличия единичных битов в операнде источник.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
06
ZF
r
Применение:
Команду bsr используют при работе на битном уровне для определения позиции крайних слева единичных битов.

Например, сдвинем содержимое регистра bx вправо таким образом, чтобы старший единичный бит исходного значения в bx переместился в нулевую позицию:
.386
        mov     bx,41h
...
        bsr     cx,bx   ;cx=06h
        jz      null
        shr     bx,ax   ;bx=0001h
...
null:...
        
См. также: уроки 9, 12 и команду bsf

BSWAP

(Byte SWAP)
Перестановка байтов
 
Схема команды:  bswap источник 
Назначение: Под формой адресации здесь понимается принцип "младший байт по младшему адресу" или обратный ему. Существует ряд систем, например использующих микропроцессоры Motorola или большие ЭВМ, где применяется принцип размещения многобайтовых значений обратный тому, который используется в микропроцессорах Intel. Поэтому эту команду можно использовать для разработки программ-конверторов между подобными платформами и IBM РС.

Синтаксис
Алгоритм работы: Схема алгоритма
Состояние флагов после выполнения команды:

выполнение команды не влияет на флаги
Применение:
Команду bswap используют для изменения формы адресации. В качестве операнда может быть указан только 32-разрядный регистр. Эта команда используется в моделях микропроцессоров, начиная с i486.
.486
        mov     ebx,1a2c345fhh
        bswap   ebx     ;ebx=5f342c1ah
        
См. также: урок 7, и команду xchg

BT

(Bit Test)
Проверка битов
 
Схема команды:  bt источник,индекс 
Назначение: извлечение значения заданного бита в флаг cf.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
00
CF
r
Применение:
Команду bt используют для определения значения конкретного бита в операнде источник. Номер проверяемого бита задается содержимым второго операнда (значение числом из диапазона 0...31). После выполнения команды, флаг cf устанавливается в соответствии со значением проверяемого бита.
.386
        mov     ebx,01001100h
        bt      ebx,8   ;проверка состояния бита 8 и установка cf= в 1
        jc      m1      ;перейти на m1, если проверяемый бит равен 1
...
        
См. также: уроки 9, 12 и команды btc, btr, bts, test

BTC

(Bit Test and Complement)
Проверка бита с инверсией (дополнением)
 
Схема команды:  btc источник,индекс 
Назначение: извлечение значения заданного бита в флаг cf и изменение его значения в операнде на обратное.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
00
CF
r
Применение:
Команда btс используется для определения и инвертирования значения конкретного бита в операнде источник. Номер проверяемого бита задается содержимым второго операнда индекс (значение из диапазона 0...31). После выполнения команды флаг cf устанавливается в соответствии с исходным значением бита, то есть тем, которое было до выполнения команды.
.386
        mov     ebx,01001100h
;проверка состояния бита 8 и его обращение:
        btc     ebx,8   ;cf=1 и ebx=01001000h
        
См. также: уроки 9, 12 и команды bt, btr, bts, test

BTR

(Bit Test and Reset)
Проверка бита с его сбросом в 0
 
Схема команды:  btr источник,индекс 
Назначение: извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
00
CF
r
Применение:
Команда btr используется для определения значения конкретного бита в операнде источник и его сброса в 0. Номер проверяемого бита задается содержимым второго операнда индекс (значение из диапазона 0...31). В результате выполнения команды флаг cf устанавливается в соответствии со значением исходного бита, то есть тем, что было до выполнения операции.
.386
        mov     ebx,01001100h
;проверка состояния бита 8 и его сброс в 0
        btr     ebx,8   ;cf=1 и ebx=01001000h
        
См. также: уроки 9, 12 и команды bt, btc, bts, test

BTS

(Bit Test and Set)
Проверка бита с его установкой в 1
 
Схема команды:  bts источник,индекс 
Назначение: извлечение значения заданного бита операнда в флаг cf и установка этого бита в единицу.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
00
CF
r
Применение:
Команда bts используется для определения значения конкретного бита в операнде источник и установки проверяемого бита в 1. Номер проверяемого бита задается содержимым второго операнда индекс (значение из диапазона 0...31). После выполнения команды флаг cf устанавливается в соответствии со значением исходного бита, то есть тем, что было до выполнения операции.
.386
        mov     ebx,01001100h
;проверка состояния бита 0 и его установка в 1
        bts     ebx,0   ;cf=0 ebx=01001001h
        
См. также: уроки 9, 12 и команды bt, btc, btr, test

CALL

(CALL)
Вызов процедуры или задачи
 
Схема команды:  call цель 
Назначение: Синтаксис
Алгоритм работы:
определяется типом операнда: Состояние флагов после выполнения команды (кроме переключения задачи):
выполнение команды не влияет на флаги
При переключении задачи значения флажков изменяются в соответствии с информацией о регистре eflags в сегменте состояния TSS задачи, на которую производится переключение.
Применение:
Как видно из описания алгоритма, команда call позволяет организовать гибкую и многовариантную передачу управления на подпрограмму с сохранением адреса точки возврата. Подробно типовые примеры использования рассмотрены на уроках 10 и 14.
См. также: уроки 10, 14 и команду ret

CBW/CWDE

(Convert Byte to Word/Convert Word to Double Word Extended)
Преобразование байта в слово/слова в двойное слово
 
Схема команды:  cbw 
cwde 
Назначение: расширение операнда со знаком.

Синтаксис
Алгоритм работы:
cbw — при работе команда использует только регистры al и ax:

cwde — при работе команда использует только регистры ax и eax: Состояние флагов после выполнения команды:
выполнение команды не влияет на флаги
Применение:
Данные команды используются для приведения операндов к нужной размерности с учетом знака. Такая необходимость может, в частности, возникнуть при программировании арифметических операций.
.386    ;только для cwde, cwd была для i8086
        mov     ebx,10fecd23h
        mov     ax,-3   ;ax=1111 1111 1111 1101
        cwde    ;eax=1111 1111 1111 1111 1111 1111 1111 1101
        add     eax,ebx
        
См. также: урок 8 и команды cdq, cwd

CLC

(CLear Carry flag)
Сброс флага переноса
 
Схема команды:  clc 
Назначение: сброс флага переноса cf.

Синтаксис
Алгоритм работы:
установка флага cf в ноль.
Состояние флагов после выполнения команды:

00
CF
0
Применение:
Данная команда используется для сброса флага cf в ноль. Такая необходимость может возникнуть при работе с командами сдвига, арифметическими командами либо действиями по индикации обнаружения ошибок и различных ситуаций в программе.
        clc             ;cf=0
        
См. также: уроки 8, 9 и команды cmc, stc

CLD

(CLear Direction flag)
Сброс флага направления
 
Схема команды:  cld 
Назначение: сброс в ноль флага направления df.

Синтаксис
Алгоритм работы:
установка флага df в ноль.
Состояние флагов после выполнения команды:

10
DF
0
Применение:
Данная команда используется для сброса флага df в ноль. Такая необходимость может возникнуть при работе с цепочечными командами. Нулевое занчение флага df вынуждает микропроцессор при выполнении цепочечных операций производить инкремент регистров si и di.
        cld             ;df=0
        
См. также: урок 11 и команды stc, movs/movsb/movsw/movsd,
cmps/cmpsb/cmpsw/cmpsd, scas/scasb/scasw/scasd,
lods/lodsb/lodsw/lodsd, stos/stosb/stosw/stosd,
ins/insb/insw/insd, outs

CLI

(CLear Interrupt flag)
Сброс флага прерывания
 
Схема команды:  cli 
Назначение: сброс флага прерывания if.

Синтаксис
Алгоритм работы:
установка флага if в ноль.
Состояние флагов после выполнения команды:

09
IF
0
Применение:
Данная команда используется для сброса флага if в ноль. Такая необходимость может возникнуть при разработке программ обработки прерываний.
        cli             ;if=0
        
См. также: урок 15 и команды int, iret/iretd, sti

CMC

(CoMplement Carry flag)
Инвертирование флага переноса
 
Схема команды:  cmc 
Назначение: изменение значения флага переноса cf на обратное.

Синтаксис
Алгоритм работы:
инвертирование значения флага переноса cf.
Состояние флагов после выполнения команды:

00
CF
r
Применение:
Данная команда используется для изменения значения флага cf на противоположное. В частности, этот флаг можно использовать для связи с процедурой и по его состоянию судить о результате работы данной процедуры. После выхода из процедуры этот флаг можно проанализировать командой условного перехода jc.
proc1   proc
...
        cmc
...
proc1   endp
...
        call    proc1
        jc      m1      ;если cf=1, то переход на m1
...
m1:
...
        
См. также: уроки 8, 9, 15 и команды clc, stc, jc, jnc

CMP

(CoMPare operands)
Сравнение операндов
 
Схема команды:  cmp операнд1,операнд2 
Назначение: сравнение двух операндов.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
r r r r r
Применение:
Данная команда используется для сравнения двух операндов методом вычитания, при этом операнды не изменяются. По результатам выполнения команды устанавливаются флаги. Команда cmp применяется с командами условного перехода и командой установки байта по значению setcc.
len     equ     10
...
        cmp     ax,len
        jne     m1      ;переход если (ax)<>len
        jmp     m2      ;переход если (ax)=len
        
См. также: уроки 10, 11, 12 и команды cmps/cmpsb/cmpsw/cmpsd, cmpxchg, sub, jcc, setcc

CMPS/CMPSB/CMPSW/CMPSD

(CoMPare String Byte/Word/Double word operands)
Сравнение строк байтов/слов/двойных слов
 
Схема команды:  cmps приемник,источник 
cmpsb 
cmpsw 
cmpsd
Назначение: сравнение двух последовательностей (цепочек) элементов в памяти.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
r r r r r
Применение:
Команды без префиксов осуществляют простое сравнение двух элементов в памяти. Размеры сравниваемых элементов зависят от применяемой команды. Команда cmps может работать с элементами размером в байт, слово, двойное слово. В качестве операндов в команде указываются идентификаторы последовательностей этих элементов в памяти. Реально эти идентификаторы используются лишь для получения типов элементов последовательностей, а их адреса должны быть предварительно загружены в указанные выше пары регистров. Транслятор, обработав команду cmps и выяснив тип операндов, генерирует одну из машинных команд cmpsb, cmpsw или cmpsd. Машинного аналога для команды cmps нет. Для адресации назначения обязательно должен использоваться регистр es, а для адресации источника можно делать замену сегмента с использованием соответствующего префикса.
Для того чтобы эти команды можно было использовать для сравнения последовательности элементов, имеющих размерность байт, слово, двойное слово, необходимо использовать один из префиксов repe или repne. Префикс repe заставляет циклически выполняться команды сравнения до тех пор, пока содержимое регистра ecx/cx не станет равным нулю или пока не совпадут очередные сравниваемые элементы цепочек (флаг zf=1). Префикс repne заставляет циклически производить сравнение до тех пор, пока не будет достигнут конец цепочки (ecx/cx=0) либо не встретятся различающиеся элементы цепочек (флаг zf=0).
.data
obl1    db      'Строка для сравнения'
obl1    db      'Строка для сравнения'
a_obl1  dd      obl1
a_obl2  dd      obl2
.code
...
        cld             ;просмотр цепочки в направлении возрастания адресов
        mov     cx,20   ;длина цепочки
        lds     si,a_obl1       ;адрес источника в пару ds:si
        les     di,a_obl2       ;адрес назначения в пару ds:si
repe    cmpsb           ;сравнивать, пока равны
        jnz     m1      ;если не конец цепочки, то встретились разные элементы
...                     ;действия, если цепочки совпали
...
m1:
...                     ;действия, если цепочки не совпали
        
См. также: уроки 10, 11 и команды ins, lods, movs, outs, scas, stos, repe, repz, repne, repnz

CMPXCHG

(CoMPare and eXCHanGe)
Сравнение и обмен
 
Схема команды:  cmpxchg приемник,источник(аккумулятор) 
Назначение: сравнение и обмен значений между источником и приемником.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
r r r r r
Применение:
Команды сравнивают два операнда. Один из сравниваемых операндов находится в аккумуляторе (регистре al/ax/eax), другой может находиться в памяти или регистре общего назначения. Если значения равны, то производится замена содержимого операнда приемник содержимым источника, находящимся в регистре-аккумуляторе. Если значения не равны, то производится замена содержимого операнда источника находящимся в регистре-аккумуляторе содержимым операнда назначения. Определить тот факт, была ли произведена смена значения в аккумуляторе (то есть были ли не равны сравниваемые операнды), можно по значению флага zf.
.486
        mov     ax,114eh
        mov     bx,8e70h
        cmpxchg bx,ax
        jz      m1      ;переход, если zf=1, то есть операнды равны
                        ;и ax не изменился
...                     ;действия, если операнды не равны
m1:
        
См. также: уроки 7, 10 и команды cmp, xchg

CWD

(Convert Word to Double word)
Преобразование слова в двойное слово
 
Схема команды:  cwd 
Назначение: расширение слова со знаком до размера двойного слова со знаком.

Синтаксис
Алгоритм работы:
копирование значения старшего бита регистра ax во все биты регистра dx. Состояние флагов после выполнения команды:

выполнение команды не влияет на флаги
Применение:
Команда cwd используется для расширения значения знакового бита в регистре ax на биты регистра dx. Данную операцию, в частности, можно использовать для подготовки к операции деления, для которой размер делимого должен быть в два раза больше размера делителя, либо для приведения операндов к одной размерности в командах умножения, сложения, вычитания.
        mov     ax,25
...
        mov     bx,4
        cwd
        div     bx
        
См. также: урок 8 и команды cbw, cdq, cwde, div, idiv, mul, imul, add, adc, sub, sbb

CDQ

(Convert Double word to Quad word)
Преобразование двойного слова в учетверенное слово
 
Схема команды:  cdq 
Назначение: расширение двойного слова со знаком до размера учетверенного слова (64 бита) со знаком.

Синтаксис
Алгоритм работы:
копирование значения старшего бита регистра eax на все биты регистра edx. Состояние флагов после выполнения команды:

выполнение команды не влияет на флаги
Применение:
Команду cdq можно использовать для распространения значения знакового бита в регистре eax на все биты регистра edx. Данную операцию, в частности, можно использовать для подготовки к операции деления, для которой размер делимого должен быть в два раза больше размера делителя.
.386
delimoe dd      ...
delitel dd      ...
...
        mov     eax,delimoe
        cdq
        idiv    delitel ;частное в eax, остаток в edx
        
См. также: урок 8 и команды cbw, cwd, cwde, div, idiv

DAA

(Decimal Adjust for Addition)
Десятичная коррекция после сложения
 
Схема команды:  daa 
Назначение: коррекция упакованного результата сложения двух BCD-чисел в упакованном формате.

Синтаксис
Алгоритм работы:
команда работает только с регистром al и анализирует наличие следующих ситуаций:

Если имеет место одна из этих двух ситуаций, то регистр al корректируется следующим образом: Состояние флагов после выполнения команды (в случае, если были переносы):
11 07 06 04 02 00
OF SF ZF AF PF CF
r r r 1 1
Состояние флагов после выполнения команды (в случае, если переносов не было):
11 07 06 04 02 00
OF SF ZF AF PF CF
r r r 0 0
Применение:
Эту команду следует применять после сложения двух упакованных BCD-чисел с целью корректировки получающегося двоичного результата сложения в правильное двузначное десятичное число. После команды daa следует анализировать состояние флага cf. Если он равен 1, то это говорит о том, что был перенос единицы в старший разряд и это нужно учесть для сложения старших десятичных цифр BCD-числа.
        mov     al,69h  ;69h — упакованное BCD-число
        mov     bl,74h  ;74h — упакованное BCD-число
        adc     al,bl   ;al=0ddh
        daa             ;cf=1, al=43h
;если перенос, то переход на ту ветвь программы,
;где он будет учтен:
        jc m1
        
См. также: урок 8, Приложение 7 и команды aaa, aad, aam, aas, das

DAS

(Decimal Adjust for Subtraction)
Десятичная коррекция после вычитания
 
Схема команды:  das 
Назначение: коррекция упакованного результата вычитания двух BCD-чисел в упакованном формате.

Синтаксис
Алгоритм работы:
команда das работает только с регистром al и анализирует наличие следующих ситуаций:

Если имеет место одна из этих ситуаций, то регистр al корректируется следующим образом: Состояние флагов после выполнения команды (в случае, если были переносы):
11 07 06 04 02 00
OF SF ZF AF PF CF
r r r 1 1
Состояние флагов после выполнения команды (в случае, если переносов не было):
11 07 06 04 02 00
OF SF ZF AF PF CF
r r r 0 0
Применение:
Команду das следует применять после вычитания двух упакованных BCD-чисел с целью корректировки получающегося двоичного результата вычитания в правильное двузначное десятичное число. После команды das следует анализировать состояние флага cf. Если он равен 1, то это говорит о том, что был заем единицы в старший разряд и это нужно учесть в дальнейших действиях. Если у вычитаемого нет больше старших разрядов, то результат следует трактовать как отрицательное двоичное дополнение. Для определения его абсолютного значения нужно вычесть 100 из результата в al. Если у вычитаемого еще есть старшие разряды, то факт заема нужно просто учесть уменьшением младшего из этих оставшихся старших разрядов на единицу.
        mov     ah,08h  ;ah=08h
        mov     al,05h  ;al=05h
        add     al,ah   ;al=al+ah=05h+08h=0dh — не BCD-число
        xor     ah,ah   ;ah=0
        aaa             ;ah=01h,al=03h — результат скорректирован
        
См. также: урок 8, Приложение 7 и команды aaa, aad, aam, aas, daa

DEC

(DECrement operand by 1)
Уменьшение операнда на единицу
 
Схема команды:  dec операнд 
Назначение: уменьшение значения операнда в памяти или регистре на 1.

Синтаксис
Алгоритм работы:
команда вычитает 1 из операнда. Состояние флагов после выполнения команды:

11 07 06 04 02
OF SF ZF AF PF
r r r r
Применение:
Команда dec используется для уменьшения значения байта, слова, двойного слова в памяти или регистре на единицу. При этом заметьте то, что команда не воздействует на флаг cf.
        mov     al,9
...
        dec     al      ;al=8
        
См. также: урок 8 и команды inc, sub

DIV

(DIVide unsigned)
Деление беззнаковое
 
Схема команды:  div делитель 
Назначение: выполнение операции деления двух двоичных беззнаковых значений.

Синтаксис
Алгоритм работы:
Для команды необходимо задание двух операндов — делимого и делителя. Делимое задается неявно и размер его зависит от размера делителя, который указывается в команде:

Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
? ? ? ? ?
Применение:
Команда выполняет целочисленное деление операндов с выдачей результата деления в виде частного и остатка от деления. При выполнении операции деления возможно возникновение исключительной ситуации: 0 — ошибка деления. Эта ситуация возникает в одном из двух случаев: делитель равен 0 или частное слишком велико для его размещения в регистре eax/ax/al.
        mov     ax,10234
        mov     bl,154
        div     bl      ;ah=остаток, al=частное
        
См. также: урок 8, приложение 7 и команду idiv

ENTER

(setup parameter block for ENTERing procedure)
Установка кадра стека для параметров процедуры
 
Схема команды:  enter loc_size,lex_lev 
Назначение: установка границы в стеке для локальных переменных процедуры.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
выполнение команды не влияет на флаги
Применение:
Команда enter специально введена в систему команд микропроцессора для поддержки блочно-структурированных языков высокого уровня типа Pascal или С. В этих языках программа разбивается на блоки. В блоках можно описать свои собственные (локальные) идентификаторы, которые не могут быть использованы вне этого блока. К примеру, на рисунке ниже в виде блоков изображена структура некоторой программы.
Изображение структуры некоторой программы в виде блоков

В правом верхнем углу каждого блока (процедуры) стоит номер лексического уровня вложенности этого блока относительно других блоков программы. Большинство блочно-структурированных языков в качестве основного метода распределения памяти для переменных в блоках используют автоматическое распределение памяти. Это означает, что при входе в блок (вызове процедуры и т. п.) в некотором месте памяти (или в стеке) выделяется область памяти для переменных этого блока (ее можно назвать областью инициализации). После выхода из этого блока связь программы с этой областью теряется, то есть эти переменные становятся недоступными. Но если, как в нашем примере, в этой процедуре есть вложенные блоки (процедуры), то для некоторого внутреннего блока (например, C) могут быть доступны области инициализации (переменные) блоков, объемлющих данный блок. В нашем примере для блока C доступны также переменные блоков B и A, но не D. Возникает вопрос: как же программа, находясь в конкретной точке своего выполнения, может отслеживать то, какие области инициализации ей доступны? Это делается с помощью структуры данных, называемой дисплеем. Дисплей содержит указатели на самую последнюю область текущего блока и на области инициализации всех блоков, объемлющих данный блок в программе. Например, если в программе A была вызвана сначала процедура B, а затем C, то дисплей содержит указатели на области инициализации A, B и C (см. рисунок ниже).

Если после этого вызвать процедуру D (в то время как B и C еще не завершены), то картина изменится.

После того как некоторый блок (процедура) завершает свою работу, ее область инициализации удаляется из памяти (стека) и одновременно соответствующим образом корректируется дисплей. Большинство языков высокого уровня хранят локальные данные блоков в стеке. Эти переменные называют еще автоматическими или динамическими. Память для них резервируется путем уменьшения значения регистра-указателя стека esp/sp на величину, равную длине области, занимаемой этими динамическими переменными. Доступ к этим переменным осуществляется посредством регистра ebp/bp. Если один блок вложен в другой, то для его динамических (локальных) переменных также выделяется место (кадр) в стеке, но в этот кадр помещается указатель на кадр стека для включающего его блока. Команды enter и leave как раз и позволяют поддержать в языке ассемблера принципы работы с переменными блоков как в блочно-структурированных языках. Дисплей организуется с помощью второго операнда команды enter и стека. Например, в начале работы главной процедуры A и после вызова процедуры B кадр стека будет выглядеть так.

Соответственно, после вызова процедур C и D стек будет выглядеть, как показано ниже.

Таким образом, видно, что используя дисплей, мы фактически имеем адреса областей инициализации, доступных по признаку вложенности объемлющих блоков. Обратный процесс завершения работы с блоками и удаления соответствующих областей инициализации поддерживается командой leave.
.286
proc1   proc
;зарезервировать в стеке место для локальных переменных
;proc1 16 байт
;лексический уровень вложенности 0
        enter   16,0
...
        leave
        ret
proc1   endp
        
См. также: урок 14 и команды leave, ret

HLT

(HaLT)
Остановка
 
Схема команды:  hlt 
Назначение: остановка микропроцессора до прерывания или перезагрузки.

Синтаксис
Алгоритм работы:
перевод микропроцессора в состояние остановки.
Состояние флагов после выполнения команды:

выполнение команды не влияет на флаги
Применение:
В результате выполнения команды микропроцессор переходит в состояние остановки. Из этого состояния его можно вывести сигналами на входах RESET, NMI, INTR. Если для возобновления работы микропроцессора используется прерывание, то сохраненное значение пары cs:eip/ip указывает на команду, следующую за hlt. Для иллюстрации применения данной команды рассмотрим еще один способ переключения микропроцессора из защищенного в реальный режим и его возврата обратно в реальный режим (см. урок 16). Как известно, в микропроцессоре не предусмотрено специальных средств для подобного переключения. Сброс микропроцессора можно инициировать, если вывести байт со значением 0feh в порт клавиатуры 64h. После этого микропроцесор переходит в реальный режим и управление получает программа BIOS, которая анализирует байт отключения в CMOS-памяти по адресу 0fh. Для нас интерес представляют два значения этого байта — 5h и 0ah: Таким образом, если вы не используете прерываний, то достаточно установить байт 0fh в CMOS-памяти в 0ah. Предварительно, конечно, вы должны инициализировать ячейку области данных BIOS 0040:0067 значением адреса, по которому необходимо передать управление после сброса. Для программирования CMOS-памяти используются номера портов 070h и 071h. Вначале в порт 070h заносится нужный номер ячейки CMOS-памяти, а затем в порт 071h — новое значение этой ячейки.
;работаем в реальном режиме, готовимся к переходу
;в защищенный режим:
        push    es
        mov     ax,40h
        mov     es,ax
        mov     word ptr es:[67h],offset ret_real
;ret_real — метка в программе, с которой должно
;начаться выполнение программы после сброса
        mov     es:[69h],cs
        mov     al,0fh  ;будем обращаться к ячейке 0fh в CMOS
        out     70h,al
        jmp     $+2     ;чуть задержимся, чтобы аппаратура отработала
;сброс без перепрограммирования контроллера
        mov     al,0ah
        out     71h,al
;переходим в защищенный режим установкой
;бита 0 cr0 в 1 (см. урок 16)
;работаем в защищенном режиме
;готовимся перейти обратно в реальный режим
        mov     al,01fch
        out     64h,al  ;сброс микропроцессора  hlt
;остановка до физического окончания процесса сброса
        ret_real:       ...     ;метка, на которую будет передано
                        ;управление после сброса
        
См. также: уроки 15, 16, 17

IDIV

(Integer DIVide)
Деление целочисленное со знаком
 
Схема команды:  idiv делитель 
Назначение: операция деления двух двоичных значений со знаком.

Синтаксис
Алгоритм работы:
Для команды необходимо задание двух операндов — делимого и делителя. Делимое задается неявно, и размер его зависит от размера делителя, местонахождение которого указывается в команде:

Остаток всегда имеет знак делимого. Знак частного зависит от состояния знаковых битов (старших разрядов) делимого и делителя.
Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
? ? ? ? ?
Применение:
Команда выполняет целочисленное деление операндов с учетом их знаковых разрядов. Результатом деления являются частное и остаток от деления. При выполнении операции деления возможно возникновение исключительной ситуации: 0 — ошибка деления. Эта ситуация возникает в одном из двух случаев: делитель равен 0 или частное слишком велико для его размещения в регистре eax/ax/al.
;деление слов
        mov     ax,1045 ;делимое
        mov     bx,587  ;делитель
        cwd             ;расширение делимого dx:ax
        idiv    bx      ;частное в ax, остаток в dx
        
См. также: урок 8, приложение 7 и команду div

IMUL

(Integer MULtiply)
Умножение целочисленное со знаком
 
Схема команды:  imul множитель_1 
imul множ_1,множ_2 
imul рез-т,множ_1,множ_2
Назначение: операция умножения двух целочисленных двоичных значений со знаком.

Синтаксис
Алгоритм работы:
Алгоритм работы команды зависит от используемой формы команды. Форма команды с одним операндом требует явного указания местоположения только одного сомножителя, который может быть расположен в ячейке памяти или регистре. Местоположение второго сомножителя фиксировано и зависит от размера первого сомножителя:

Результат умножения для команды с одним операндом также помещается в строго определенное место, определяемое размером сомножителей: Команды с двумя и тремя операндами однозначно определяют расположение результата и сомножителей следующим образом: Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
r ? ? ? r
Команда imul устанавливает в ноль флаги of и cf, если размер результата соответствует регистру назначения. Если эти флаги отличны от нуля, то это означает, что результат слишком велик для отведенных ему регистром назначения рамок и необходимо указать больший по размеру регистр для успешного завершения данной операции умножения. Конкретными условиями сброса флагов of и cf в ноль являются следующие условия: Применение:
Команда выполняет целочисленное умножение операндов с учетом их знаковых разрядов. Для выполнения этой операции необходимо наличие двух сомножителей. Размещение и задание их местоположения в команде зависит от формы применяемой команды умножения, которая, в свою очередь, определяется моделью микропроцессора. Так, для микропроцессора i8086 возможна только однооперандная форма команды, для последующих моделей микропроцессоров дополнительно можно использовать двух- и трехоперандные формы этой команды.
.486
...
        mov     bx,186
        imul    eax,bx,8
;если результату не хватило размерности операнда1,
;то перейдем на m1, где скорректируем ситуацию:
        jc      m1
        
См. также: урок 8, приложение 7 и команду mul

IN

(INput operand from port)
Ввод операнда из порта
 
Схема команды:  in аккумулятор,ном_порта 
Назначение: ввод значения из порта ввода-вывода.

Синтаксис
Алгоритм работы:
Передает байт, слово, двойное слово из порта ввода-вывода в один из регистров al/ax/eax. Состояние флагов после выполнения команды: выполнение команды не влияет на флаги.
Состояние флагов после выполнения команды:

выполнение команды не влияет на флаги
Применение:
Команда применяется для прямого управления оборудованием компьютера посредством портов. Номер порта задается вторым операндом в виде непосредственного значения или значения в регистре dx. Непосредственным значением можно задать порт с номером в диапазоне 0-255. При использовании порта с большим номером используется регистр dx. Размер данных определяется размерностью первого операнда и может быть байтом, словом, двойным словом. В качестве примера применения рассмотрим фрагмент обработчика прерывания от клавиатуры 9. Это прерывание вызывается всякий раз при нажатии любой клавиши на клавиатуре. Обработчик этого прерывания должен прочитать скан-код клавиши, подтвердить микропроцессору клавиатуры факт приема скан-кода, преобразовать этот код в соответствии с клавишами-переключателями и поместить преобразованный код в буфер клавиатуры, находящийся в области BIOS. Действия чтения и подтверждения приема скан-кода могут выглядеть, к примеру, так:
        in      al,60h  ;читаем скан-код
        push    ax      ;сохраним его на время
        in      al,61h  ;читаем порт 61h
        or      al,80h  ;старший бит байта из порта 61h в 1
        out     61h,al  ;подтверждаем факт приема скан-кода
        pop     ax
        out     61h,al  ;восстановили байт в порту 61h
        
См. также: урок 7 и команды out, ins/insb/insw/insd, outs

INC

(INCrement operand by 1)
Увеличить операнд на 1
 
Схема команды:  inc операнд 
Назначение: увеличение значения операнда в памяти или регистре на 1.

Синтаксис
Алгоритм работы:
команда увеличивает операнд на единицу.
Состояние флагов после выполнения команды:

11 07 06 04 02
OF SF ZF AF PF
r r r r
Применение:
Команда используется для увеличения значения байта, слова, двойного слова в памяти или регистре на единицу. При этом команда не воздействует на флаг cf.
        inc     ax      ;увеличить значение в ax на 1
        
См. также: урок 8 и команды dec, add, adc

INS/INSB/INSW/INSD

(Input String Byte/Word/Double word operands)
Ввод строк байтов/слов/двойных слов из порта
 
Схема команды:  ins приемник,порт 
insb 
insw 
insd
Назначение: ввод из порта в память последовательности байт, слов, двойных слов.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
выполнение команды не влияет на флаги
Применение:
Команда вводит данные из порта ввода-вывода, номер которого загружен в регистр dx, в память по адресу es:edi/di. Сегментная составляющая адреса должна быть обязательно в регистре es. Замена сегментного регистра недопустима. Непосредственное задание порта в команде также недопустимо - для этого используется регистр dx. Размеры вводимых элементов зависят от применяемой команды. Команда ins может работать с элементами размером в байт, слово, двойное слово. В качестве операндов в команде указывается символическое имя ячейки памяти, в которую вводятся элементы из порта ввода-вывода. Реально это символическое имя используется лишь для получения типа элемента последовательности, а его адрес должен быть предварительно загружен в пару регистров es:edi/di. Транслятор, обработав команду ins и выяснив тип операнда, генерирует одну из машинных команд insb, insw или insd. Машинного аналога для команды ins нет. Для того чтобы эти команды можно было использовать для ввода последовательности элементов, имеющих размерность байт, слово, двойное слово, необходимо использовать префикс rep. Префикс rep заставляет циклически выполняться команду ввода до тех пор, пока содержимое регистра ecx/cx не станет равным нулю.
.286
;ввести 10 байт из порта 300h (номер порта bgr условно)
;в цепочку байт в памяти по адресу
str_10  db      10 dup(0)
adr_str dd      str_10
        les     di,adr_str
        mov     dx,300h
rep     insb
...
        
См. также: уроки 2, 11 и команды cmps/cmpsb/cmpsw/cmpsd, lods/lodsb/lodsw/lodsd, movs/movsb/movsw/movsd, outs, scas/scasb/scasw/scasd, stos/stosb/stosw/stosd, rep/repe/repz/repne/repnz

INT

(INTerrupt)
Вызов подпрограммы обслуживания прерывания
 
Схема команды:  int номер_прерывания 
Назначение: вызов подпрограммы обслуживания прерывания с номером прерывания, заданным операндом команды.

Синтаксис
Алгоритм работы:

Состояние флагов после выполнения команды:
09 08
IF TF
0
Применение:
Как видно из синтаксиса, существуют две формы этой