На этом шаге мы познакомимся с основными арифметическими командами.
Перечислим основные арифметические команды, используемые для организации вычислений.
Определяет двоичную сумму двух указанных операндов. | |
Определяет двоичную сумму двух указанных операндов и содержимого флага переноса CF. | |
Увеличивает содержимое операнда на 1. | |
Определяет разность уменьшаемого и вычитаемого. | |
Определяет разность двух операндов, и, кроме того, из уменьшаемого вычитается содержимое флага переноса. | |
Уменьшает содержимое операнда на единицу. | |
Производит беззнаковое умножение содержимого аккумулятора (регистра AL при байтовом умножении и регистра AX при умножении слов) на указанный операнд. | |
Производит умножение аккумулятора на указанный операнд с учетом знаков. | |
Осуществляет деление содержимого аккумулятора (AX при байтовом делении или пары регистров DX и AX при делении слов) на указанный операнд без учета знаков. | |
Выполняет деление содержимого аккумулятора (AX при делении байтовых чисел или пары регистров DX и AX при делении слов) на указанный операнд с учетом знаков. | |
Пересылает данные из одного операнда в другой. | |
Меняет местами содержимое двух операндов. | |
Меняет знак операнда на противоположный. |
Рассмотрим более подробно перечисленные команды.
1. ADD (Сложение). Определяет двоичную сумму двух указанных операндов. Результат помещается на место операнда-приемника, второй операнд остается без изменения. Общий вид:
ADD <1-й операнд>, <2-й операнд> <1-й операнд> <-- <1-й операнд> + <2-й операнд> .
Местом хранения первого операнда может быть регистр или ячейка памяти; второго операнда - регистр или ячейка памяти, либо он может быть задан константой. Не разрешается использовать для записи операндов сегментные регистры, а также ячейки памяти для одновременного хранения двух операндов. Операнды могут быть числами со знаком или без него и представлять собой байты или слова.
содержимое регистра DL: 0101 10002 = 58H ; содержимое ячейки TEST_BYTE: 0010 01112 = 27H; новое содержимое ячейки TEST_BYTE: 0111 11112 = 7FH.
Флаги, затрагиваемые операцией: OF, ZF, AF, PF, CF.
2. ADC (Сложение с переносом). Определяет двоичную сумму двух указанных операндов и содержимого флага переноса CF. Результат помещается на место операнда-приемника, второй операнд остается без изменений. Общий вид:
ADC <1-й операнд>, <2-й операнд> <1-й операнд> <-- <1-й операнд> + <2-й операнд> + <CF> .
Команда работает с байтами и со словами, со знаковыми и беззнаковыми двоичными числами. Первый операнд может храниться в регистре или ячейке памяти. Второй операнд может быть задан в регистре, ячейке памяти или непосредственным числовым значением. Не разрешается задавать операнды в регистрах сегментов, а также хранение (запись) двух операндов одновременно в ячейках памяти. Операнды могут быть байтами или словами, представлять числа со знаком или без знака. Поскольку команда ADC использует флаг переноса CF, то она может применяться для сложения чисел, длина которых превышает 16 бит.
содержимое BX: 0100 1000 0000 0011 = 4803H; содержимое AX: 0010 0101 0001 0111 = 2517H; флаг переноса CF: 1 ; новое содержимое AX: 0110 1101 0001 1011 = 6D1BH.
224810H 23E1ADH
Сначала сложим младшие слова этих чисел, используя команду ADD:
4810H E1ADH ------ (1)29BDH
Единица в скобках - это значение флага CF. Одновременно это значение, которое должно быть перенесено в следующий разряд. Мы должны его учесть при сложении старших разрядов этих чисел. Поэтому нужно воспользоваться командой ADC:
22H 23H 1H ;Перенос от предыдущей операции. ------ 46H
4629BDH .
Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.
3. INC (Инкремент). Увеличивает содержимое операнда на 1. Общий вид:
INC <операнд> <операнд> <-- <операнд> + 1 .
Операнд может быть задан в регистре общего назначения или в ячейке памяти. Сегментные регистры не могут быть использованы для хранения операндов. Команда INC может использоваться как с однобайтовыми, так и двухбайтовыми операндами. Операнды интерпретируются как числа без знака. Команда воздействует на флаги OF, SF, ZF, AF, PF.
Замечание. Выражение [BX] сообщает Ассемблеру, что регистр BX содержит адрес операнда, а не является операндом сам по себе. Скобки [ и ], заключающие какое-либо значение, указывают Ассемблеру, что это значение - адрес. Другая часть выражения, WORD PTR, требуется Ассемблеру для информации, что операнд является переменной типа WORD (слово).
4. SUB (Вычитание). Определяет разность уменьшаемого и вычитаемого. Результат помещается на место уменьшаемого, вычитаемое остается без изменений. Общий вид:
SUB <1-й операнд>, <2-й операнд> <1-й операнд> <-- <1-й операнд> - <2-й операнд> .
Первый операнд может быть задан в регистре или ячейке памяти. Второй операнд может быть задан в регистре, ячейке памяти или непосредственно константой. Не допускается использование сегментных регистров или одновременная запись этих операндов в ячейках памяти. Операнды могут быть как знаковыми, так и беззнаковыми числами. Возможно выполнение 8- и 16-разрядных операций.
Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.
5. SBB (Вычитание с заемом). Определяет разность двух операндов, и, кроме того, из уменьшаемого вычитается содержимое флага переноса:
SBB <1-й операнд>, <2-й операнд> <1-й операнд> <-- <1-й операнд> - <2-й операнд> - <CF> .
Результат помещается на место первого операнда, предыдущее значение которого теряется. Содержимое второго операнда не изменяется.
Первый операнд может быть задан в регистре или ячейке памяти. Второй операнд, кроме того, может быть задан константой. Не допускается использовать для записи операндов сегментные регистры или задавать оба операнда в ячейках памяти. Операнды могут быть однобайтовыми или двухбайтовыми числами со знаком или без знака. Возможность заема позволяет использовать команду SBB для организации вычитания чисел с разрядностью, превышающей 16 бит.
6. DEC (Декремент). Уменьшает содержимое операнда на единицу:
DEC <операнд> <операнд> <-- <операнд> - 1 .
Операнд может храниться в регистре общего назначения или ячейке памяти. Не допускается задание операндов в регистрах сегментов. Операция выполняется как над однобайтовыми, так и над двухбайтовыми числами. Операнд рассматривается как беззнаковое число. Команда DEC не воздействует на флаг CF.
Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF.
7. MUL (Умножение). Производит беззнаковое умножение содержимого аккумулятора (регистра AL при байтовом умножении и регистра AX при умножении слов) на указанный операнд. Общий вид:
MUL <операнд>
Если операнд является байтом, то он умножается на содержимое регистра AL и результат двойной длины (слово) записывается в регистр AX. Если операнд - слово, то он умножается на содержимое регистра AX и результат (двойное слово) записывается в пару регистров DX и AX, причем регистр DX содержит старшие разряды результата. Операнд может быть задан в регистре общего назначения или ячейке памяти и интерпретируется как число без знака. Описанный порядок выполнения команды умножения сведен в таблицу 2.
Если содержимое регистра AH после однобайтового умножения или содержимое регистра DX после двухбайтового умножения не равны нулю, флаги CF и OF устанавливаются в 1. В противном случае они сбрасываются в 0. Состояние флагов SF, ZF, AF, PF после команды MUL не определено.
Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.
8. IMUL (Умножение целых чисел с учетом знака). Производит умножение аккумулятора на указанный операнд с учетом знаков. Результатом байтового умножения является 16-битовое число, хранящееся в регистре AX. Результат умножения слов - 32-битовое число в паре регистров DX и AX, причем в DX - старшие 16 бит результата. Если старшая часть (AH при байтовом умножении или DX при длинах операндов, равных слову) содержит не знак младшей части результата, а его значащие цифры, флаги CF и OF переводятся в единичное состояние. В противном случае оба флага обнуляются. После выполнения IMUL состояние флагов AF, PF, SF и ZF становится неопределенным.
Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.
9. DIV (Деление). Осуществляет деление содержимого аккумулятора (AX при байтовом делении или пары регистров DX и AX при делении слов) на указанный операнд без учета знаков. Общий вид:
DIV <операнд>
Результат выполнения команды деления приведен в таблице 3.
Таким образом, при 8-битовом делении целая часть отношения помещается в регистр AL, а остаток - в регистр AH. При этом, если результат деления будет больше FFH, то генерируется прерывание типа 0 (ошибка при делении).
Для двухбайтовых операций выполняется деление содержимого регистровой пары DX:AX на указанный операнд. Если результата деления больше FFFFH, то генерируется прерывание типа 0. При 16-битовом делении целая часть отношения размещается в регистре AX, а остаток - в регистре DX.
Операнд может быть задан в регистре общего назначения или ячейке памяти, при этом операнд рассматривается как беззнаковый 8- или 16-битовый делитель соответственно при однобайтовом и двухбайтовом делении.
После выполнения команды DIV состояния разрядов регистра флагов процессора не определены. Если произошло переполнение, то частное и остаток не определены.
Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.
10. IDIV (Деление чисел с учетом знака). Выполняет деление содержимого аккумулятора (AX при делении байтовых чисел или пары регистров DX и AX при делении слов) на указанный операнд с учетом знаков. При 8-битовом делении отношение размещается в регистре AL, а остаток - в регистре AH. При 16-битовом делении регистр AX содержит частное, а регистр DX - остаток. При байтовом делении максимальное положительное частное не превышает 127 (7FH), а минимальное отрицательное не может быть меньше -127 (81H). При делении чисел длиной в слово максимальное положительное отношение равно 32767 (7FFFH), а минимальное отрицательное частное равно -32767 (8001H). Если отношение меньше допустимого минимума или больше максимума или если произведена попытка деления на 0, микропроцессор автоматически генерирует прерывание типа 0 (прерывание из-за ошибки деления). Отношение всегда усекается до целой части. Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.
11. Для написания простейших программ на языке Ассемблера необходима еще одна команда, непосредственно не относящаяся с арифметическим командам. Это команда MOV (Пересылка данных):
MOV <1-й операнд>, <2-й операнд> <1-й операнд> <-- <2-й операнд> .
Второй операнд при выполнении команды MOV занимает место хранения первого операнда. При этом первый операнд теряется.
Первый операнд может быть задан в регистре общего назначения, регистре сегмента (кроме регистра CS) или ячейки памяти. Второй операнд, кроме того, может быть еще и константой. Команда MOV работает как с однобайтовыми, так и с двухбайтовыми словами.
12. Команда замены XCHG меняет местами содержимое двух операндов. Эта команда может поменять местами содержимое двух регистров, или регистра и памяти. При этом в качестве операндов не могут использоваться сегментные регистры. Общий вид:
XCHG <1-й операнд>, <2-й операнд> <1-й операнд> <--> <2-й операнд> .
13. Иногда, зная положительное число, требуется получить противоположное ему отрицательное число. Для этого используется команда NEG, обеспечивающая преобразование знака двоичных чисел из положительного в отрицательное и наоборот. Общий вид:
NEG <операнд> .
На следующем шаге мы рассмотрим основные логические команды.