Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
прогр.docx
Скачиваний:
23
Добавлен:
21.12.2018
Размер:
2.58 Mб
Скачать

1111111011101101 Инвертируем 0000000100010010

+ 0000000000000001

= 00000001000100112 = 27510

или (neg(1111111011101101b))= 0000000100010011b=275d

При сложении чисел разных знаков:

1) если в результате получаем sf=0; cf=1, то значение в приёмнике будет верным и положительным.

2) если в результате получаем sf=1; cf=0, то значение в приёмнике будет верным в дополнительном коде и отрицательным.

При выполнении команды сложения устанавливаются следующие флаги:

1) CF=1 , если результат не помещается в приемнике, т.е. произойдет перенос.

2) PF=1; если результат имеет четное число битов с 1.

3) AF=1, если результат сложения десятичных чисел требует коррекции.

4) ZF=1, если результат =0.

5) SF= 1, если результат отрицателен.

6) OF=1, если при сложении 2-х чисел одного знака результат превышает диапазон допустимых значений в обратном коде, а сам приемник меняет знак. SF и OF имеют смысл при сложении чисел со знаком, AF – для десятичных чисел.

Вычитание двоичных чисел без знака

Команды вычитания выполняют вычитание, по рассмотренным алгоритмам, а учёт особых ситуаций должен производиться самим разработчиком программного продукта.

К командам вычитания относят:

DEC <операнд> – операция декремента. Флаг CF не затрагивается, а остальные арифметические флаги (OF, SF, ZF, AF, PF) устанавливаются в соответствии с результатом вычитания.

SUB <операнд_1>,<операнд_2> – команда вычитания;

Принцип действия:

операнд_1=операнд_1-операнд_2.

Нельзя использовать переменную одновременно и для операнд_2, и для операнд_1. Команда SUB не делает различий между числами со знаком и без знака.

SBB <операнд_1>,<операнд_2> – команда вычитания с учётом заёма (флага cf).

Принцип действия:

операнд_1=операнд_1-операнд_2-значение_cf.

Пример: вычтем из одного 64-битного числа, хранящегося в EDX:EAX другое, хранящееся в ЕВХ:ЕСХ.

sub eax,ecx

sbb edx,ebx

Если при вычитании младших двойных слов произошел заем, то он будет учтен при вычитании старших.

Пример: в регистр al поместить результат вычитания 5-10.

0000 0101

-

0000 1010

-----------------

1111 1011=FFFBh

(0-1111 1011)

1 0000 0000

-

1111 1011

=

0000 0101(neg)

Факт того, что в al записано отрицательное число, отражён в состоянии флага cf.

Вычитание двоичных чисел со знаком

Вычитание в микропроцессоре производится путём сложения. Результат вычитания нужно рассматривать как значение в дополнительном коде. Например:

-45-45=-90

-45= 11010011

+

-45= 11010011

=

-90=1 10100110 в приёмнике число в дополнительном коде. (sf=1; of=1;)

01011001

+00000001

=010110102 =9010

Умножение двоичных чисел без знака

Для умножения чисел без знака предназначена команда:

MUL <источник>;

Выполняет умножение содержимого источника (регистр или переменная) и регистра AL, АХ, ЕАХ (в зависимости от размера источника) и помещает результат в АХ, DX:AX, EDX:EAX соответственно. Произведение имеет двойной размер.

Размер Источник Результат (приёмник)

Если АН, DX, EDX содержит только нули, то флаги CF=0 и OF=0, иначе — в 1.

Например, умножим содержимое регистра al (25) на 45.

Умножение двоичных чисел со знаком

IMUL <операнд_1>[, операнд_2, операнд_3]; умножение чисел со знаком.

Эта команда имеет три формы, различающиеся числом операндов:

1) IMUL <операнд_1>: операнд_1 (регистр или переменная) умножается на AL, АХ или ЕАХ (в зависимости от размера операнда), и результат располагается в АХ, DX:AX или EDX:EAX соответственно.

2) IMUL <операнд_1>,<операнд_2>: операнд_2 (число, регистр или переменная) умножается на операнд_1 (регистр), и результат заносится в операнд_1.

3) IMUL <операнд_1>,<операнд_2>,<операнд_3>: операнд_2 (регистр или переменная) умножается на операнд_3 (число), и результат заносится в операнд_1 (регистр).

Произведение имеет двойной размер

В первом случае приемник (регистры АХ, DX:AX или EDX:EAX) всегда больше операнд_1.

Если результат мал и умещается в одном регистре (то есть если cf=of=0), то содержимое другого регистра (старшей части) является расширением знака – все его биты равны старшему биту (знаковому разряду) младшей части результата.

В противном случае (если cf=of=1) знаком результата является знаковый бит старшей части результата, а знаковый бит младшей части является значащим битом двоичного кода результата.

Пример: mul bl ;al*bl, результат в Ах.

Пример: mul bx ;ax*bx, результат Dx:Ax.