Справочник по языку Ассемблера IBM PC

       

Вычитание проводится по правилам двоичной


Результат вычитания больше 9
  6 = 0000 0110  -   7 = 0000 0111  =  -1 = 1111 1111
Вычитание проводится по правилам двоичной арифметики. Поэтому результат не является BCD-числом.
Правильный результат в неупакованном BCD-формате должен быть 9 (0000 1001 в двоичной системе счисления). При этом предполагается заем из старшего разряда, как при обычной команде вычитания, то есть в случае с BCD числами фактически должно быть выполнено вычитание 16 – 7. Таким образом видно, что, как и в случае сложения, результат вычитания нужно корректировать. Для этого существует специальная команда:
aas (ASCII Adjust for Substraction) — коррекция результата вычитания для представления в символьном виде.
Команда aas также не имеет операндов и работает с регистром al, анализируя его младшую тетраду следующим образом:

    если ее значение меньше 9, то флаг cf сбрасывается в 0 и управление передается следующей команде;
    если значение тетрады в al больше 9, то команда aas выполняет следующие действия:
    из содержимого младшей тетрады регистра al (заметьте — не из содержимого всего регистра) вычитает 6;
    обнуляет старшую тетраду регистра al;
    устанавливает флаг cf в 1, тем самым фиксируя воображаемый заем из старшего разряда.
    Понятно, что команда aas применяется вместе с основными командами вычитания sub и sbb. При этом команду sub есть смысл использовать только один раз, при вычитании самых младших цифр операндов, далее должна применяться команда sbb, которая будет учитывать возможный заем из старшего разряда. В листинге 9 мы обходимся одной командой sbb, которая в цикле производит поразрядное вычитание двух BCD-чисел.
    Листинг 9. Вычитание неупакованных BCD-чисел <1> ;prg_8_9.asm <2> masm <3> model small <4> stack 256 <5> .data ;сегмент данных <6> b db 1,7 ;неупакованное число 71 <7> c db 4,5 ;неупакованное число 54 <8> subs db 2 dup (0) <9> .code <10> main: ;точка входа в программу <11> mov ax,@data ;связываем регистр dx с сегментом <12> mov ds,ax ;данных через регистр ax <13> xor ax,ax ;очищаем ax <14> lenequ 2 ;разрядность чисел <15> xor bx,bx <16> mov cx,len ;загрузка в cx счетчика цикла <17> m1: <18> mov al,b[bx] <19> sbb al,c[bx] <20> aas <21> mov subs[bx],al <22> inc bx <23> loop m1 <24> jc m2 ;анализ флага заема <25> jmp exit <26> m2:... <27> exit: <28> mov ax,4c00h ;стандартный выход <29> int 21h <30> end main ;конец программы  

    Данная программа не требует особых пояснений, когда уменьшаемое больше вычитаемого. Поэтому обратите внимание на строку 24. С ее помощью мы предусматриваем случай, когда после вычитания старших цифр чисел был зафиксирован факт заема. Это говорит о том, что вычитаемое было больше уменьшаемого, в результате чего разность будет неправильной. Эту ситуацию нужно как-то обработать. С этой целью в строке 24 командой jc анализируется флаг cf. По результату этого анализа мы уходим на ветку программы, обозначенную меткой m2, где и будут выполняться некоторые действия. 

    Содержание раздела