Вычитание десятичных чисел
Аналогично сложению, корректируются результаты вычитания при операциях с BCD-числами. Операция aas корректирует результат вычитания неупакованной десятичной цифры из другой неупакованной десятичной цифры. Команда не имеет операндов и работает с регистром al по следующему алгоритму:
1) если значение в регистре меньше или равно 9, то флаг cf устанавливается в 0 и управление передается следующей команде;
2) если значение в регистре al больше 9,
а) из содержимого младшей тетрады этого регистра вычитается 6,
б) обнуляется старшая тетрада регистра al;
в) флаг cf устанавливается в 1, тем самым фиксируя наличие заема из предыдущего воображаемого разряда.
Проблему в операциях с десятичными числами создают ситуации, когда уменьшаемое меньше вычитаемого. В этом случае результат является отрицательным, однако, для десятичных чисел нет представления отрицательных значений. Выявление и обработка таких ситуаций полностью ложится на плечи программиста, что свидетельствует о том, что алгоритмы арифметических действий в ассемблере нужно разрабатывать более тщательно и подробнее, чем в языках программирования высокого уровня.
Для упакованных BCD-чисел коррекцию результата вычитания производят командой das. Как и в предыдущей команде коррекции, результат предполагается в регистре al, но теперь в обеих его тетрадах.
Дадим некоторые пояснения относительно арифметического переноса и переполнения.
Перенос – это выход за пределы разрядной сетки, переполнение – неверный результат операции из-за недостаточной разрядности сетки. Рассмотрим на примерах.
Таблица 2 - Примеры сложения чисел
Двоичные значения |
Беззнаковая десятичная |
итог |
Знаковая десятичная |
итог |
OF |
CF |
11111100 +00000101 (1)00000001 |
252 + 5 1 |
неверно |
-4 +5 1 |
верно |
0 |
1 |
01111001 +00001011 10000100 |
121 +11 132 |
верно |
121 +11 132 |
неверно |
1 |
0 |
11110110 +10001001 (1)01111111 |
246 +137 127 |
неверно |
-10 -119 +127 |
неверно |
1 |
1 |
В рассмотренных примерах первый столбец таблицы содержит двоичные значения складываемых переменных, следующие 2 столбца показывают результат, если складываемые переменные интерпретируются как беззнаковые числа (значения переменных переводятся в десятичную систему счисления и складываются), далее 4-ый и 5-ый столбец показывают результат, если эти же двоичные значения интерпретируются, как знаковые значения. Последние 6-ой и 7-ой столбцы таблицы показывают, как устанавливаются флаги переноса (cf) и переполнения (оf) при выполнении операции суммирования (add).
Проанализировав данные из таблицы, можно сделать вывод:
если складываются беззнаковые переменные, о выходе результата за разрядную сетку свидетельствует установка в 1 флага переноса cf;
если складываются знаковые переменные, о неверном результате свидетельствует установка в 1 флага переполнения of.
Из рассмотренных примеров следует вывод, что нужно четко представлять себе величины подлежащих обработке чисел и выбирать числовые элементы данных (описания переменных в сегменте данных) подходящих типов.
