Читать «Assembler. Программирование на языке ассемблера IBM PC» онлайн - страница 37

Unknown Author

Команда NEG рассматривает свой операнд как число со знаком и меняет его знак на противоположный: ор:=-ор. Например:

HOV АН,1

NEG АН ;АН:=-1 (OFFh)

Здесь есть особый случай: если ор=-128 (80h), то операнд не меняется, т. к. нет знакового числа +128. Аналогично для чисел-слов: если значение операнда равно минимальному отрицательному числу -32768 (8000h), то команда не меняет операнд.

В этом особом случае флаг OF получает значение 1 (при других операндах OF=0). При нулевом операнде флаг CF равен 0, при других - 1. Флаги SF и ZF меняются как обычно.

И, наконец, рассмотрим еще пару команд сложения и вычитания:

*

Сложение с учетом переноса (add with carry):    ADC opl, op2

Вычитание с учетом эаема (subtract with borrow): SBB opl,op2

Допустимые типы операндов - как в командах ADD и SUB.

Эти команды аналогичны командам обычного сложения и вычитания (ADD и SUB) за одним исключением - в команде ADC к сумме операндов еще при-

бавляется значение флага переноса CF: op 1:=ор 1 +op2+CF, а в команде SBB из разности операндов еще вычитается значение этого флага: opl:=opl-op2-CF.

Зачем это нужно? В ПК одной командой можно сложит*» (вычесть) только числа размером в байт или слово. Сложение же (вычитание) чисел других размеров, например двойных слов, приходится реализовывать нам самим через сложение (вычитание) чисел размером в слово или байт. Здесь-то и оказываются полезными команды ADC и SBB.

Рассмотрим, для примера, как можно сложить следующие два числа размером в двойное слово: X=1204F003h и Y=8052300Fh. Условно разбиваем каждое число на два слова. Сначала складываем младшие (правые) части их, используя команду ADD. Может получиться единица переноса, которую надо учесть при сложении старших (левых) частей чисел. Как это сделать? Вспомним, что единица переноса попадает в флаг CF, поэтому к сумме старших частей надо добавить и значение этого флага (если единицы переноса не было, то CF=0, поэтому и здесь можно прибавлять CF), а такое сложение как раз и осуществляет команда ADC. Следовательно, старшие части чисел надо складывать по команде ADC.

X

SS

1204

F003

+

+

Y

г=

8052

300F

9256

12012

+

1

1 <-

CF

9257

2012

Если для определенности считать, что число X размещается в двух регистрах АХ (старшие цифры) и ВХ (младшие), а число Y - в регистрах СХ (старшие цифры) и DX (младшие), и если сумму этих двух чисел надо записать вместо числа X, т. е. надо реализовать (AX,BX):=(AX,BX)+(CX,DX), тогда это делается так:

ADD BX,DX    ;ВХ:-Хмл+Умл, CF-перенос

ADC АХ,СХ    ;АХ: =*Xct+Yct+CF

{Отметим, что при сложении старших частей также может появиться единица переноса, однако мы ее уже не будем учитывать.)

Аналогичным образом реализуется вычитание беззнаковых чисел размером в двойное слово, для чего используется команда SBB. Например, вычитание (AX,BX):=(AX,BX)-(CX,DX) реализуется так:

SUB BX,DX    ;£Х: =Хмл-Умл, СЕ=заеь*    единицы

SBB АХ,СХ    ?AX:=Xct-Yct-CF

С помощью команд ADC и $ВВ можно реализовать сложение и вычитание чисел любого размера, причем эти операции для беззнаковых и знаковых чисел реализуются одинаково.