Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Микропроцессорные системы (книга Комаров) / Программирование на Ассемблере (ч 2).doc
Скачиваний:
155
Добавлен:
08.03.2015
Размер:
380.93 Кб
Скачать

Команды расширения знака

К этой подгруппе относятся команды CBW и CWD, не имеющие операндов и предназначенные для преобразования форматов чисел со знаком путем его расширения.

Команда CBW преобразует байт из регистра AL в слово в регистре AX путем дублирования бита D7 из AL во всех битах AH.

Команда CWD преобразует слово из регистра AX в двойное слово в регистрах DX,AX путем дублирования бита D15 из AX во всех битах регистра DX.

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

Пример 3.65:

Вычислить арифметическую сумму S=A+B, где A и B - байты со знаком.

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

MOV AL, A ; Расширение первого

CBW ; операнда

MOV DX, AX

MOV AL, B ; Расширение второго

CBW ; операнда

ADD AX, DX ; Сложение операндов

MOV S, AX

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

Пример 3.66:

; Сложение разноформатных однотипных чисел

MOV AL, Alfa ; Сложение байта со знаком Alfa

CBW ; и слова со знаком Beta

ADD AX, Beta ; из памяти

; Сложение одноформатных разнотипных чисел

MOV DL, Alpha ; Расширение байта без

MOV DH, 0 ; знака

MOV AL, Beta ; Расширение байта со

CBW ; знаком

ADD AX, DX ; Сложение разнотипных байтов

Команды умножения и деления

К этой подгруппе относятся команды MUL,IMUL и DIV,IDIV.

Команда MUL выполняет умножение чисел без знака, а команда IMUL - умножение чисел со знаком. Обе команды могут умножать как байты, так и слова и записываются в формате:

MUL источник

Imul источник.

В качестве источника может указываться 8-битный или 16-битный регистр общего назначения или ячейка памяти. Содержимое источника служит первым операндом операции умножения. Второй операнд по умолчанию берется из регистра AL (при умножении на байт) или из регистра AX (при умножении на слово). Произведение имеет двойной размер и возвращается в регистрах AX или DX,AX соответственно. Таким образом, команды MUL и IMUL реализуют операции:

(AX) = (AL)  источник8,

(DX,AX) = (AX)  источник16.

Пример 3.67:

MUL BX ;Умножение без знака (DX,AX)=(AX)(BX)

IMUL DL ;Умножение со знаком (AX)=(AL)(DL)

MUL BYTE PTR[BX] ;Умножение без знака на байт ; из памяти:(AX)=(AL)((BX))

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

Пример 3.68:

MOV DL, 10 ; Умножение на константу

MUL DL ; (AX) = (AL)  10

После выполнения команд MUL и IMUL флаги переноса CF и переполнения OF показывают, какая часть произведения существенна для последующих операций. Флаги CF=OF=1, если старшая половина произведения равна 0 (для MUL) или содержит лишь расширение знака младшей половины (для IMUL); в противном случае CF=OF=0. Состояние остальных арифметических флагов изменяется неопределенным образом.

Команда DIV выполняет деление чисел без знака, а команда IDIV - деление чисел со знаком. Обе команды могут делить как на байт, так и на слово и записываются в формате:

DIV источник

IDIV источник.

В качестве источника может указываться 8-битный или 16-битный регистр общего назначения или ячейка памяти. Содержимое источника служит делителем операции деления. Делимое имеет двойной размер и по умолчанию берется из регистра AX (при делении на байт) или из регистров DX,AX (при делении на слово). Результат деления представляет собой частное и остаток и возвращается следующим образом:

при делении на байт:

частное - в регистре AL, остаток - в регистре AH;

при делении на слово:

частное - в регистре AX, остаток - в регистре DX.

Таким образом, команды DIV и IDIV реализуют операции:

(AL) = (AX)/(источник8), (AH) = (AX)mod(источник8),

(AX) = (DX,AX)/(источник16), (DX) = (DX,AX)mod(источник16),

где mod - операция формирования остатка от целочисленного деления.

Пример 3.69:

DIV BX ;Деление без знака (DX,AX) на (BX) IDIV DL ;Деление со знаком (AX) на (DL)

IDIV WORD PTR[DI] ;Деление со знаком (DX,AX) на слово ;из памяти

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

Пример 3.70:

MOV BX, 20 ; Деление (DX,AX) на

IDIV BX ; константу 20

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

Например, (-26)/(+7)=-3(остаток=-5) или (-26)/(+7)=-4(остаток=+2). Любой из полученных результатов верен, так как справедливо проверочное соотношение для деления: делимое = делитель  частное + остаток.

При выполнении команды IDIV остатку всегда присваивается знак делимого, и для рассмотренного примера результатом будет частное=-3, остаток=-5.

Если при выполнении команд DIV и IDIV делитель равен 0 или частное не помещается в регистре-приемнике (AL или AX), то автоматически генерируется прерывание по ошибке деления типа 0. В этом случае частное и остаток не определены, а управление передается подпрограмме обработки прерывания, которая принимает все необходимые решения.

Команды DIV и IDIV оставляют все арифметические флаги в неопределенном состоянии.

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

Пример 3.71:

; Умножение знаковых байта и слова

MOV AL, Alfa ; Расширение байта Alfa

CBW

IMUL Beta ; Умножение на слово Beta

; Умножение байта со знаком на байт без знака

MOV AL, S_Byte ; Расширение байта

CBW ; со знаком

MOV DL, Byte ; Расширение байта

MOV DH, 0 ; без знака

IMUL DX ; Умножение

; Деление знаковых слова на слово

MOV AX, Alfa ; Расширение слова со

CWD ; знаком

IDIV Beta ; Деление