Буззнаковые и знаковые данные 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Буззнаковые и знаковые данные



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

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

В следующем примере сложения двух двоичных чисел первое число содержит единичный левый бит. Для беззнакового числа биты представляют положительное число 249, для знакового -отрицательное число -7:

Беззнаковое Знаковое

11111001 249 -7

00000010 2 +2

11111011 251 -5

Двоичное представление результата сложения одинаково для беззнакового и знакового числа. Однако биты представляют + 251 для беззнакового числа и -5 для знакового. Таким образом, числовое содержимое поля может интерпретироваться по-разному.

Состояние переноса возникает в случае, когда имеется перенос в знаковый разряд. Состояние переполнения возникает в случае, когда перенос в знаковый разряд не создает переноса из разрядной сетки или перенос из разрядной сетки происходит без переноса в знаковый разряд.

Если при сложении беззнаковых чисел возникает перенос, то результат получается неправильным:

Беззнаковое Знаковое CF OF

11111100 252 -4

00000101 5 +5

00000001 1 1 1 0

(неправильно)

В случае возникновения переполнения при сложении знаковых чисел результат получается неправильный:

Беззнаковое Знаковое CF OF

01111001 121 +121

00001011 11 +11

10000100 132 -124 0 1

(неправильно)

При операциях сложения и вычитания может одновременно возникнуть и переполнение и перенос:

Беззнаковое Знаковое CF OF

11110110 246 -10

10001001 137 -119

01111111 127 +127 1 1

(неправильно) (неправильно)

Умножение

Операция умножения для беззнаковых данных выполняется командой MUL, а для знаковых - IMUL (Integer MULtiplication -умножение целых чисел).

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

Умножение байта на байт.

Умножение слова на слово.

MULTB DB 1Ah

MULTW DW 2E13H

MULTD DD 0B2E13CAH

IMUL EBX, MULTW;Умножение слова I-32 на слово I-32,

;результат слово I-32 в регистре EBX

MUL MULTB;Умножение байта на байт, результат в рег.AX

IMUL MULTW;Умножение слова I-32 (Двойного слова) на;слово I-32, результат четверное слово(64 bit)

; в регистрах EDX:EAX

Рис. 4.25 Фрагмент программы с операциями умножения

На рис 4.25 приведены варианты применения команды умножения. Как было сказано в разделе 4.11.1, в результате умножения двух 32-разрядных чисел получается произведение двойной длины, то есть 64-разрядное значение. Однако для многих приложений достаточно иметь результат одинарной длины, то есть 32-разрядное значение. В подобных ситуациях используются разные команды. Команда, приведенная на рисунке первой, умножает 32 разрядные сомножители, результат получается тоже 32 разрядный. Исход­ный операнд может находиться либо в регистре, либо в памяти. В случае 64-раз­рядного результата команда в единственном операнде команд MUL и IMUL указывается множитель, множимое уже должно находиться в AL или EAX соответственно. Рассмотрим следующую команду:

MUL MULTB

Так как поле MULTB определено как байт (DB), то операция предполагает умножение содержимого AL на значение байта из поля MULTB.

Если поле MULTD определено по терминологии Intel как двойное слово (DD) или слово I-32, то операция предполагает умножение содержимого EAX на значение слова из поля MULTD.

Умножение байта на байт. Множимое уже находится в регистре AL, а множитель - в байте памяти или в однобайтовом регистре. После умножения произведение находится в регистре AX. Операция игнорирует и стирает любые данные, которые находились в регистре АН.

До АН AL После AX

умножения: Множимое Множитель умножения: произведение

Умножение слова на слово. Множимое находится в регистре EAX, а множитель - в слове памяти или в регистре. После умножения произведение образуется в двойном слове, для которого требуется два регистра: старшая (левая) часть произведения находится в регистре EDX, а младшая (правая) часть - в регистре EAX. Операция игнорирует и стирает любые данные, которые были в регистре EDX.

До | EAX | После EDX EAX

умножения: |Множимое | умножения: Старшая Младшая

Часть часть

Произведение

Если множитель находится в регистре, то длина регистра определяет тип операции, как показано ниже:

MUL CL;Байт-множитель: множимое в AL, произведение в AX

MUL BX;Слово-Множитель: множимое в AX, произведение в DX:AX

MUL EBX;Двойное слово-Множитель: множимое в EAX, произведение в EDX:EAX

 

Беззнаковое умножение: команда MUL

Команда MUL (MULtiplication - умножение) перемножает беззнаковые числа. На рис. 4.26 в процедуре C10MUL дано три примера умножения: байт на байт, слово на слово и слово на байт.

Первый пример команды MUL перемножает 80Н (128) на 47Н (64). Произведение 2000Н (8192) получается в регистре AX.

Второй пример команды MUL генерирует 10000000Н в регистрах DX:AX.

Третий пример команды MUL перемножает слово на байт и требует расширения байта BYTE1 до размеров слова. Так как предполагаются беззнаковые данные, то в примере левый бит регистра АН равен нулю. (При использовании команды CBW значение левого бита регистра AL может быть 0 или 1.) Произведение 00400000Н получается в регистровой паре DX:AX.

Знаковое умножение: команда IMUL

Команда IMUL (Integer MULtiplication - умножение целых чисел) перемножает знаковые числа. На рис. 4.26 в процедуре D10IMUL используются те же три примера умножения, что и в процедуре C10MUL, но вместо команд MUL записаны команды IMUL.

page 60,132

TITLE EXMULT (СОМ) Пример команд умножения

CODESG SEGMENT PARA 'Code'

ASSUME CS:CODESG,DS:CODESG,SS:CODESG

ORG 100H

BEGIN: JMP SHORT MAIN

;

BYTE1 DB 80H

BYTE2 DB 40H

WORD1 DW 8000H

WORD2 DW 4000H

;

MAIN PROC NEAR;Основная процедура:

CALL C10MUL;Вызвать умнож. MUL

CALL D10IMUL;Вызвать умнож. IMUL

RET

MAIN ENDP

; Пример умножения MUL:

C10MUL PROC

MOV AL, BYTE1;Байт * байт

MUL BYTE2;произведение в AX

MOV AX,WORD1;Слово * слово

MUL WORD2;произведение в DX:AX

MOV AX,WORD1;Слово * слово

MUL AX,WORD2;!!! произведение в EAX

MOV AL, BYTE1;Байт * слово

SUB АН, АН.;расшир.множимого. в АН

MUL WORD1;произведение в DX:AX

RET

C10MUL ENDP

; Пример умножения IMUL:

D10 IMUL PROC

MOV AL, BYTE1;Байт * байт

IMUL BYTE2;произведение в AX

MOV AX,WORD1;Слово * слово

IMUL WORD2;произвед, в DX:AX

MOV AL,BYTE1;Байт * слово

CBW;расшир. множимого в АН

IMUL WORD1;произвед, в DX:AX

RET

D10 IMUL ENDP

CODESG ENDS

END BEGIN

Рис.4.26. Беззнаковое и знаковое умножение

Первый пример команды IMUL перемножает 80H (отрицательное число) на 40H (положительное число). Произведение Е000H получается в регистре AX. Используя те же данные, команда MUL дает в результате 2000 (12810 (80H) * 6410 (40H) = 819210 или 2000H, а команда IMUL дополняет результат знаковыми единицами и получает Е000H), так что можно видеть разницу в использовании команд MUL и IMUL. Команда MUL рассматривает 80H как +128, а команда IMUL - как -128. В результате умножения -128 на +64 получается -8192 или шестнадцатиричное Е000. (Попробуйте преобразовать Е000 в десятичный формат.)

Второй пример команды IMUL перемножает 8000H (отрицательное значение) на 2000Н (положительное значение). Произведение F0000000 получается в регистрах DX:AX и представляет собой отрицательное значение.

Третий пример команды IMUL перед умножением выполняет расширение байта BYTE1 до размеров слова в регистре AX. Так как значения предполагаются знаковые, то в примере используется команда CBW для перевода левого знакового бита в регистр АН:

шестнадцатиричное 80 в регистре AL превращается в FF80 в регистре AX. Поскольку множитель в слове WORD1 имеет также отрицательное значение, то произведение будет положительным. В самом деле, 00400000Н в регистрах DX:AX - такой же результат, как и в случае умножения командой MUL, которая предполагала положительные сомножители.

Таким образом, если множимое и множитель имеют одинаковый знаковый бит, то команды MUL и IMUL генерируют одинаковый результат. Но если сомножители имеют разные знаковые биты, то команда MUL вырабатывает положительный результат умножения, а команда IMUL - отрицательный.

Можно обнаружить это, используя трассировкe примеров.

Повышение эффективности умножения.

При умножении на степень числа 2 (2,4,8 и т.д.) более эффективен сдвиг влево на требуемое число битов. Сдвиг более чем на 1 требует загрузки счетчика сдвига в регистр CL. В следующих примерах предположим, что множимое находится в регистре AL или AX:

Умножение на 2:

SHL AL,1

Умножение на 8:

MOV CL,3

SHL AX,CL

Многословноe умножение

Обычно умножение бывает двух типов: умножение байта на байт и умножение слова на слово. Как было показано, максимальное знаковое значение в слове + 32767. Умножение больших чисел требует выполнения некоторых дополнительных действий. Рассматриваемый подход предполагает умножение каждого слова отдельно и затем сложение полученных результатов.

Рассмотрим следующее умножение в десятичном формате:

x12

1365

 

Представим, что Десятичная арифметика может умножать только двузначные числа. Тогда можно умножить 13 и 65 на 12 раздельно:

13 65

x12x12

26 130

13 65

156 780

Теперь сложим полученные произведения, но поскольку число 13 представляло сотни, то первое произведение в действительности будет 15600:

15600 +780 =16380

Ассемблерная программа использует аналогичную технику, за исключением того, что данные имеют размерность двойных слов (четыре цифры) в шестнадцатеричном формате.

Умножение двойного слова на слово. Процедура E10XMUL на рис. 4.27 умножает двойное слово на слово.

Множимое MULTCND состоит из двух слов, содержащих соответственно 3206Н и 2521Н. Определение данных в виде двух слов (DW) вместо двойного слова (DD) обусловлено необходимостью правильной адресации для команд MOV, пересылающих слова в регистр AX.

Множитель MULTPLR содержит 6400Н.

Область для записи произведения PRODUCT состоит из трех слов.

Первая команда MUL перемножает MULTPLR и правое слово поля MULTCND; произведение 0Е80 Е400 записывается в PRODUCT+2 и PRODUCT+4.

Вторая команда MUL перемножает MULTPLR и левое слово поля MULTCND, получая в результате 138А 5800.

Далее выполняется сложение двух произведений следующим образом:

Произведение 1: 0000 0Е80 Е400 Произведение 2: 138А 5800 Результат: 138А 6680 Е400

Так как первая команда ADD может выработать перенос, то второе сложение выполняется командой сложения с переносом ADC (ADd with Carry). В силу обратного представления байтов в словах в процессорах 8086/8088 область PRODUCT в действительности будет содержать значение 8А13 8066 00Е4. Программа предполагает, что первое слово в области PRODUCT имеет начальное значение 0000.

Умножение двойного слова на двойное слово.

Умножение двух двойных слов включает следующие четыре операции умножения:

Множимое Множитель

слово 2 х слово 2

слово 2 х слово 1

слово 1 х слово 2

слово 1 х слово 1

 

TITLE EXDWMUL - Умножение двойных слов

CODESG SEGMENT PARA 'Code'

ASSUME CS:CODESG,OS:CODESG,SS:CODESG

ORG 100H

BEGIN: JMP SHORT MAIN

MULTCND DW 3206H;Элементы данных

DW 2521H

MULTPLR DW 6400Н

DW 0A26H

PRODUCT DW 0

DW 0

DW 0

DW 0

MAIN PROC NEAR;Основная процедура

CALL E10XMUL;Вызвать 1-е умножение

CALL Z10ZERO;Очистить произведение

CALL E10XMUL;Вызвать 2-е умножение

RET

MAIN ENDP

; Умножение дв.слова на слово:

E10XMUL PROC

MOV AX,MULTCND+2;Умнож. прав. cл.

MUL MULTPLR;множимого

MOV PRODUCT+4,AX;3аписать произв.

MOV PRODUCT+2,DX

MOV AX,MULTCND;Умножить лев. cл.

MUL MULTPLR;множимого

ADD PRODUCT+2,AX;Сложить с полученным ранее

ADC PRODUCT, DX

RET

E10XMUL ENDP

; Перемножение двух двойных слов:

F10XMUL PROC

MOV AX,MULTCND+2 Слово-2 множимого

MUL MULTPLR+2 * слово-2 множителя

MOV PRODUCT+6,AX Сохранить рез.

MOV PRODUCT+4,AX

MOV AX,MULTCND+2 Слово-2 множимого

MUL MULTPLR * слово-1 множителя

ADD PRODUCT+4,AX Сложить с пред.

ADC PRODUCT+6,AX

ADC PRODUCT,00 Прибавить перенос

MOV AX,MULTCND Слово-1 множимого

MUL MULTPLR+2 * Слово-2 множителя

ADC PRODUCT+4,AX Сложить с пред.

ADC PROOUCT+6,DX

ADC PRODUCT,00 Прибавить перенос

MOV AX,MULTCND Слово-1 множимого

MUL MULTPLR * слово-1 множителя

ADD PRODUCT+2,AX Сложить с пред.

ADC PRODUCT, DX,

RET

F10XMUL ENDP

; Очистка области результата:

Z10XMUL PROC

MOV PRODUCT,0000

MOV PRODUCT+2,0000

MOV PRODUCT+4,0000

MOV PRODUCT+6,0000

RET

Z10XMUL ENDP

CODESG ENDS

END BEGIN

Рис. 4.27. Многословное умножение

Каждое произведение в регистровой паре DX:AX складывается с соответствующим словом в окончательном результате. Пример такого умножения приведен в процедуре F10XMUL на рис. 4.27. Множимое MULTCND содержит 3206 2521, множитель MULTPLR -6400 0A26. Результат заносится в область PRODUCT, состоящую из четырех слов.

Хотя логика умножения двойных слов аналогична умножению двойного слова на слово, имеется одна особенность. После пары команд сложения ADD/ADC используется еще одна команда ADC, которая прибавляет 0 к значению в поле PRODUCT. Это необходимо потому, что первая команда ADC сама может вызвать перенос, который последующие команды могут стереть. Поэтому вторая команда ADC прибавит 0, если переноса нет, и прибавит 1, если перенос есть.

Финальная пара команд ADD/ADC не требует дополнительной команды ADC, так как область PRODUCT достаточно велика для генерации окончательного результата и переноса на последнем этапе не будет.

Окончательный результат 138А 687С 8Е5С ССЕ6 получится а поле PRODUCT в обратной последовательности байтов в словах.



Поделиться:


Последнее изменение этой страницы: 2016-09-13; просмотров: 373; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.105.108 (0.066 с.)