Прочие арифметические команды
Некоторые другие команды часто используются в действиях с двоичной арифметикой. Эти команды приведены в Табл. 2.
Команда EXT (Sign extend) преобразует байт или слово, находящееся в регистре, соответственно в слово или длинное слово посредством расширения бита знака.
Команда NEG (Negate) берет дополнение приёмника или, что тоже самое, меняет знак операнда. Если операндом является ноль, тогда знак не изменяется. Если для байтовых операций операнд равен $80 (-128), то операнд остаётся неизменным, но флаг V устанавливается в "1", фиксируя таким образом переполнение. Аналогичная ситуация возникает для слова $8000 и длинного слова $80000000 .
Команда NEGX (Negate with X flag) предназначена для для взятия дополнения чисел с увеличенной точностью.
Команда CLR (Clear) обнуляет операнд.
Табл. 2.
Мнемоника Размерность Формат Допустимый Действие Сост. флагов
или суффикс операнда тип EA X N Z V C
EXT .W, L Dn Dn.B, расширенное - * * 0 0
(Расширить со знаком ® Dn.W
со знаком) или Dn.W, расшир.
со знаком ® Dn.L
NEG .B, .W, .L EA Data 0-(EA)®EA * * * * *
(Инвертировать) alterable
NEGX .B, .W, .L EA Data 0-(EA)-X®EA * * * * *
(Инвертировать alterable
с расширением)
CLR .B, .W, .L EA Data 0®EA - 0 1 0 0
(Обнулить) Alterable
Для иллюстрации использования команд целочисленной арифметики напишем программу для вычисления выражения:
X=½X-5½+Y , где Х определено как длинное слово, а Y - как слово.
SUBQ.L #5,XX Вычислить разность
BGE.S PLUS Перейти, если >=
NEG XX Взять дополнение
PLUS MOVE.W YY,D0 Y переслать в регистр
EXT.L D0 Расширить знак
ADD.L D0,XX Сложить и записать результат
Команды умножения и деления
Команды двоичного умножения и деления показаны в Табл. 3. Команды умножения перемножают два 16-битовых операнда и получают 32-битовый результат, который записывается в приёмник (регистр данных). Команда MULS (Signed multiply) обрабатывает операнды как знаковые числа и получает произведение со знаком. Для команды MULU (Unsigned multiply) операнды представляются как беззнаковые числа и результат получается беззнаковым.
Опишем команду MULS:
MULSУмножение с учетом знака
Действие: (dst)¬(src) x (dst)
Ассемблер: MULS <ea>,Dn 16 x 16 = 32
Атрибут: Size = (Word)
Описание: Старшие 16 бит множимого игнорируются. Произведение в виде длинного слова со знаком записывается в регистр Dn.
Коды условий: X N Z V C
- **0 0
Режим адресации
источника: Data
Описание команды MULU идентично (за исключением того, что множимое, множитель и произведение являются беззнаковыми).
Обратите внимание, что в командах MULS и MULU переполнение никогда не возникает, так как сомножители являются 16-битовыми операндами, а результат записывается как длинное слово (32 бита). По этой же причине флаг переноса С всегда имеет нулевое значение.
Для пояснений различий команд MULS и MULU, предположим, что перед выполнением каждой из команд начальные установки следующие:
-
Операнд
Содержимое hex
Как десятичное беззнаковое
Как десятичное знаковое
Ячейка XX
0003
3
3
Ячейка YY
B000
45056
-20480
D0[15:0]
00A0
160
160
D1[15:0]
FF00
65280
-256
Выполнение каждой из команд будет приводить к следующим результатам:
MULS XX,D0 D0=000001E0 (3 ´160 = 480 десятичное)
MULU XX,D0 D0=000001E0 (3 ´160 = 480 десятичное)
MULS XX,D1 D1=FFFFFD00 (3 ´(-256) = -768 десятичное)
MULU XX,D1 D1=000001E0 (3 ´65280 = 195840 десятичное)
MULS YY,D1 D1=00500000 (-20480´(-256)=5242880 десятичное)
MULU YY,D1 D1=AF500000 (45056´65280=2941255680 десятичное)
Команды DIVS (signed divide) и DIVU (unsigned divide) предназначены для деления 32-битового делимого, хранящегося в регистре данных, на 16-битовый операнд, определённый как источник. 16-битовый остаток возвращается в старшее слово регистра данных, и 16-битовое частное помещается в младшее слово регистра. Для команды DIVS знак частного определяется алгебраическим правилом, а остаток имеет такой же знак, как и делимое.
Существуют две возможные ошибки, которые могут случиться в процессе деления. Если делитель равен 0, то деление на 0 является ошибкой, что приводит к возникновению исключительной ситуации "деление на 0" . Другая ошибка - это переполнение , которое случается, когда частное слишком велико для того, чтобы поместиться в 16 бит. Эта ошибка переполнения будет происходить, если делитель меньше, чем старшие 16 бит делимого. Переполнение устанавливает флаг V в "1" и операнд-приемник остается неизменным.
Опишем команду DIVS:
DIVSДеление с учетом знака
Действие: (dst)¬(dst) : (src)
Ассемблер: DIVS.W <ea>,Dn 32 : 16 = 16r , 16q
Атрибут: Size = (Word)
Описание: Делимое представляется в регистре Dn в виде длинного слова со знаком . Результат деления размещается в том же регистре Dn (делимое теряется): старшие 16 бит занимает остаток (remainder), а младшие 16 бит - частное (quotient).
Коды условий: X N Z V C
- ** *0
Режим адресации
источника: Data
Замечание: После выполнения операции деления флаги N и Z устанав- ливаются в соответствии с частным, а не с остатком. В случае переполнения флаги N и Z имеют неопределенные значения, а бит V устанавливаетя в 1. В случае деления на 0 флаги N, Z и V имеют неопределенные значения.
Описание команды DIVU отличается от команды DIVS только отсутствием знаков у операндов. Для иллюстрации действия команд деления, предположим, что установлено следующее содержимое регистров и ячеек памяти:
Ячейка XX: 0012 (десятичное 18)
Ячейка YY: FFAE (десятичное -82
Ячейка ZZ: FF00 (беззнаковое десятичное 65280)
Регистр D0: 00000308 (десятичное 776)
Регистр D1: FFFFFE00 (десятичное -512)
При условии, что установки будут такими перед выполнением каждой из ниже следующих команд, получим:
-
Команда
Результат
hex
Частное
десятичное
Остаток
десятичный
DIVU XX,D0
D0=0002002B
43
2
DIVS XX,D1
D1=FFF8FFE4
-28
-8
DIVS YY,D0
D0=0026FFF7
-9
38
DIVU YY,D1
D1=FFEC0006
6
-20
DIVU ZZ,D0
D0=03080000
0
776
DIVU ZZ,D1
D1=FFFFFE00
флаг V=1
В качестве примера, включающего в себя комбинацию двоичных арифметических действий, предположим, что мы хотим вычислить выражение:
X = 5 ´Y + Z / W ,
где Y, Z и W являются 16-битовыми знаковыми целыми числами, и записать результат в длинное слово Х. Последовательность команд, выполняющая эти вычисления, приведена ниже:
MOVE.W YY,D0 Записать Y в D0
MULS #5,D0 Умножить на 5
MOVE.W ZZ,D1 Записать Z в D1
EXT.L D1 Расширить знак
DIVS WW,D1 Разделить
EXT.L D1 Расширить частное
ADD.L D1,D0 Сложить
MOVE.L D0,XX Записать результат
Табл. 3
Мнемоника Размерность Формат Допустимый Действие Сост. флагов
или суффикс операнда тип EA X N Z V C
MULS Слово EA,Dn Data (EA)*Dn[15:0]®Dn - * * 0 0
(Знаковое умножение) Результат знаковый
MULU Слово EA,Dn Data (EA)*Dn[15:0]®Dn - * * 0 0
(Беззнаковое умножение) Результат беззнаковый
DIVS Слово EA,Dn Data Dn/(EA) - *1 * * 0
(Знаковое деление) Частное (знаковое)®Dn[15:0]
Остаток (тот же знак как
у делителя)®Dn[31:16]
DIVU Слово EA,Dn Data Dn/(EA) - *1 * * 0 0
(Беззнаковое деление) Частное (знаковое)®Dn[15:0]
Остаток (тот же знак как
у делителя)®Dn[31:16]
Примечание: 1. Флаги N, Z и V устанавливаются в соответствии с частным.