Часть 5. Целочисленная арифметика
1. Команды add и sub
ADD (Сложение целых) заменяет операнд назначения на сумму операнда-источника и операнда назначения. Команда оказывает воздействие на флаги OF, SF, ZF, AF, PF и CF. ADC (Сложение целых с переносом) заменяет операнд назначения на сумму операнда-источника и операнда назначения плюс 1, если флаг CF установлен. Если флаг CF сброшен, команда ADC выполняет те же действия, что и команда ADD. Команда ADC используется для поддержки переноса, когда сложение выполняется на одном из этапов, например, когда используется 32-разрядная команда ADD для сложения двух учетверенных слов-операндов. Команда оказывает воздействие на флаги OF, SF, ZF, AF, PF, и CF.
SUB (Вычитание целых) вычитает операнд-источник из операнда назначения и заменяет значение операнда назначения на полученный результат. Если возникает заем единицы, устанавливается значение флага CF. Операндами могут быть байты, слова и двойные слова со знаком и без него. Команда оказывает воздействие на флаги OF, SF, ZF, AF, PF и CF. SBB (Вычитание целых с заемом) вычитает операнд-источник из операнда назначения, заменяя значение приемника на результат вычитания минус 1, если установлен флаг CF. Если флаг CF очищен, команда SBB выполняет ту же операцию, что и команда SUB. Команда SUB используется для поддержки заема разряда, когда выполняется вычитание чисел как один из этапов, например, когда используется 32-разрядная команда SUB для вычитания одного учетверенного слова из другого. Команда оказывает воздействие на флаги OF, SF, ZF, AF, PF и CF.
Микропроцессор может выполнять целочисленные операции и операции с плавающей точкой. Для этого в его архитектуре есть два отдельных блока:
•устройство для выполнения целочисленных операций;
•устройство с плавающей точкой.
Каждое из этих устройств имеет свою систему команд. В принципе, целочисленное устройство может взять на себя многие функции устройства с плавающей точкой, но это потребует больших вычислительных затрат.
!!! Для большинства задач, использующих язык ассемблера, достаточно целочисленной арифметики.
Сложение беззнаковых чисел
Микропроцессор выполняет сложение операндов по правилам сложения двоичных чисел.
• add операнд1,операнд2 — команда сложения с принципом действия:
операнд1 = операнд1 + операнд2
· xadd назначение,источник — обмен местами и сложение.
Команда позволяет выполнить последовательно два действия:
•обменять значения назначение и источник;
•поместить на место операнда назначение сумму:
назначение = назначение + источник.
!!! В операции сложения должны участвовать операнды одного формата (b-b, w-w)
!!! Возможны сочетания регистр - регистр
память - регистр
регистр - память
регистр - непосредственный операнд
неп. Операнд - регистр
!!! Операция память - память выполняется через промежуточный регистр
Пример1 Вычисление суммы двух чисел
. . .
slag1 dw 250
slag2 dw 125
rez dw ?
. . .
mov ax,slag1
add ax,slag2
mov rez,ax
. . .
• inc операнд — операция инкремента, то есть увеличения значения операнда на 1;
операнд = операнд +1
!!! Операнд м.б. регистром или адресом памяти и !!! не м.б. непоср.операндом
Пример2. Увеличение числа на 1
Mov ax,slag1
inc ax
mov rez,ax
Особые ситуации, которые могут возникать при сложении:
1) значение результата превышает размерности поля операнда
для фиксирования ситуации выхода за разрядную сетку результата в микропроцессоре предусмотрено специальное средство: флаг переноса CF (curry flag). Он располагается в бите 0 регистра флагов eflags/flags. Именно установкой этого флага фиксируется факт переноса единицы из старшего разряда операнда. (CF=1)
Например, при сложении операндов размером в байт результат не должен превышать число 255. Если это происходит, то результат оказывается неверным.
Например, выполним сложение: 254 + 5 = 259 в двоичном виде. 11111110 + 0000101 = 1 00000011. Результат вышел за пределы восьми бит и правильное его значение укладывается в 9 бит, а в 8-битовом поле операнда осталось значение 3, что, конечно, неверно.
Т.е. если при сложении двух 8-битовых чисел результат занимает 9 битов, то значение старшего 9 бита запоминается во флажке CF.
!!! Программист должен предусматривать возможность такого исхода операции сложения Необходимо включать участки кода после операции сложения, в которых анализируется флаг cf.
Анализ этого флага можно провести различными способами.
Например, использовать команду условного перехода
jc <метка> ; Переход на метку если cf = 1
jnc <метка> ; Переход на метку если cf = 0
• adc операнд_1,операнд_2 — команда сложения с учетом флага переноса cf.
операнд_1 = операнд_1 + операнд_2 + значение_cf
это команда сложения, учитывающая перенос единицы из старшего разряда.
Пример 3. Вычисление суммы чисел
masm
model small
stack 256
.data
a db 254
.code
main:
mov ax,@data
mov ds,ax
...
xor ax,ax
add al,17
add al,a ; результат сложения выходит за границы операнда.
jnc m1 ; проверяет состояние флага cf - если нет переноса, то перейти на m1
adc ah,0 ;в ax сумма с учетом переноса в старший разряд
m1: ...
exit:
mov ax,4c00h ;стандартный выход
int 21h
end main
При сложении чисел со знаком может произойти особая ситуация
2) результат выходит из диапазона допустимых значений
Переполнение регистрируется с помощью флага переполнения of.
Дополнительно к флагу of при переносе из старшего разряда устанавливается в 1 и флаг переноса cf.
Проанализировать флаг of можно командами условного перехода jo \ jno .
учет особых ситуаций должен производиться самим программистом. !!!