3
По курсу: “Системное программирование и вычислительные системы”
На тему: “Арифметические операции с BCD числами”
Содержание:
- 1. ДВОИЧНО-ДЕСЯТИЧНЫЙ ФОРМАТ (BCD)……………………….3
- 2. Арифметические инструкции…………………………………………..4
-
- 2.1. Форматы арифметических данных…………………………………..4
- 2.2. Арифметические операции и флаги…………………………………5
- 2.3. Сложение………………………………………………………………6
- 2.4. Вычитание……………………………………………………………..7
- 2.5. Умножение…………………………………………………………….8
- 2.6. Деление…………………………………………………………………9
- 3. ЛИТЕРАТУРА………………………………………………………….12
1. ДВОИЧНО-ДЕСЯТИЧНЫЙ ФОРМАТ (BCD)
Пусть в некотором примере деления в ASCII-формате было получено частное 00090204. Если сжать это значение, сохраняя только правые цифры каждого байта, то получим 0924. Такой формат называется двоично-десятичным (BCD - Binary Coded Decimal) (или упакованным). Он содержит только десятичные цифры от 0 до 9. Длина двоично-десятичного представления в два раза меньше ASCII-представления.
Заметим, однако, что десятичное число 0924 имеет основание 10 и, будучи преобразованным в основание 16 (т.е. в шест. представление), даст шест.039C.
ПРЕОБРАЗОВАНИЕ ASCII-ФОРМАТА В ДВОИЧНЫЙ ФОРМАТ
Выполнение арифметических операций над числами в ASCII или BCD форматах удобно лишь для коротких полей. В большинстве случаев для арифметических операций используется преобразование в двоичный формат. Практически проще преобразование из ASCII-формата непосредственно в двоичный формат, чем преобразование из ASCII- в BCD-формат и, затем, в двоичный формат:
Метод преобразования базируется на том, что ASCII-формат имеет основание 10, а компьютер выполняет арифметические операции только над числами с основанием 2. Процедура преобразования заключается в следующем:
1. Начинают с самого правого байта числа в ASCII-формате и обрабатывают справа налево.
2. Удаляют тройки из левых шест. цифр каждого ASCII-байта.
3. Умножают ASCII-цифры на 1, 10, 100 (шест.1, A, 64) и т.д. и складывают результаты.
Для примера рассмотрим преобразование числа 1234 из ASCII-формата в двоичный формат:
Десятичное Шестнадцатеричное
H
4 х 1 = 4 4
3 х 10 = 30 1E
2 х 100 = 200 C8
1 х 1000 = 1000 - 3E8 -
Результат: 04D2
Из этого примера видно, что шестнадцатеричное число .04D2 действительно соответствует десятичному 1234.
2. Арифметические инструкции.
2.1. Форматы арифметических данных.
Арифметические операции процессоров 8086/8088 могут выполняться над операндами 4-х типов (таблица 2.1):
1. Двоичные без знака.
2. Двоичные со знаком (целые).
3. Упакованные десятичные без знака.
4. Распакованные десятичные без знака.
Таблица 2.1. Арифметическая интерпретация 8-битовых чисел.
|
16-ричное
|
битовое
|
дв. без
знака
|
дв. со
знаком
|
распак.
десятич.
|
упак.
десят.
|
|
07
89
C5
|
00000111
10001001
11000101
|
7
137
197
|
+7
-119
-59
|
7
некорр.
некорр.
|
7
89
некор.
|
|
|
Двоичные числа могут занимать 1 или 2 байта. Десятичные числа хранятся побайтно по 2 десятичной цифре на байт для упакованного формата или по 1 десятичной цифре на байт для распакованного формата. Процессор предполагает, что определенные в арифметических инструкциях операнды содержат данные, представляющие корректные для данной инструкции числа. Некорректные данные могут привести к непредсказуемым результатам.
Двоичные числа без знака могут занимать 8 или 16 бит; все биты значимы. Диапазон значений 8-битового числа - от 0 до 255, 16-битового - от 0 до 65535. Над двоичными числами без знака можно выполнять операции сложения, вычитания, умножения и деления.
Двоичные числа со знаком (целые) могут занимать также 8 или 16 бит. Значение старшего бита (самого левого) задает знак числа : 0 - положительное, 1 - отрицательное. Отрицательные числа представляются стандартным дополнением до 2. Поскольку один разряд отведен под знак, диапазон изменения 8-битового числа - от -127 до +127, 16-битового -от -32768 до +32767. Число 0 имеет положительный знак. Над двоичными числами со знаком могут быть выполнены операции умножения и деления. Сложение и вычитание выполняются без учета знака. Для обнаружения переноса в знаковый разряд в результате беззнаковой операции можно использовать инструкции условного перехода.
Упакованные десятичные числа хранятся как беззнаковые байтовые величины. Каждый байт содержит 2 десятичные цифры, занимающие по 4 бита каждая. Цифра в старшем полубайте более значима. В каждом полубайте допустимы только 16-ричные значения от 0 до 9; соответственно пределы изменения десятичного числа - от 0 до 99. Сложение и вычитание таких чисел выполняются в 2 стадии. Сначала применяется обычная беззнаковая двоичная инструкция, которая формирует в регистре AL промежуточный результат. Затем выполняется операция настройки (инструкция DAA или DAS), преобразующая содержимое AL в корректный упакованный десятичный результат. Умножение и деление упакованных десятичных чисел невозможно.
Распакованные десятичные числа хранятся как беззнаковые байтовые величины. Десятичная цифра располагается в младшем полубайте. Допустимы и интерпретируются как десятичные числа 16-ричные значения от 0 до 9. Для выполнения операций умножения и деления старший полубайт должен быть заполнен нулями; для сложения и вычитания он может содержать любое значение. Арифметические операции над распакованными десятичными числами выполняются в 2 стадии. Сначала используются обычные беззнаковые инструкции сложения, вычитания или умножения, которые формируют в регистре AL промежуточный результат. Затем выполняется операция настройки (инструкция AAA,AAS или AAM), преобразующая содержимое AL в результирующее корректное распакованное десятичное число. Деление выполняется аналогично, за исключением того, что сначала следует настроить числитель в AL (инструкция AAD), а затем выполнить инструкцию беззнакового двоичного деления, результатом которого будет корректное распакованное десятичное число.
Формат десятичных распакованных чисел подобен представлению десятичных цифр в коде ASCII. При этом для числа в коде ASCII старший полубайт содержит 16-ричное значение 3. Возможное содержимое старшего полубайта для распакованного формата приведено выше. Преобразование из одного вида в другой сложности не представляет.
2.2. Арифметические операции и флаги.
Арифметические инструкции процессоров 8086/8088 оставляют после своего выполнения некоторые характеристики результатов операций в виде значений 6 флагов. Большинство из них могут анализироваться последующими инструкциями условного перехода; может также использоваться инструкция прерывания по переполнению INTO. Влияние каждой инструкции на флаги указано при описании инструкции.
Однако имеются следующие общие правила:
1. Флаг переноса CF устанавливается в 1, если в результате операции сложения был перенос из старшего бита или в результате операции вычитания был заем в старший бит результата. Если же переноса или заема не было, CF устанавливается в 0. Заметим, что знаковый перенос характеризуется различными значениями флагов CF и OF. Флаг CF может использоваться для обнаружения беззнакового переполнения. Следует помнить, что 2 инструкции, ADC (сложение с переносом) и SBB (вычитание с заемом) вовлекают CF в свои операции и могут быть поэтому использованы для мультибайтного (32-, 64-разрядного) сложения и вычитания.
2. Флаг промежуточного переноса AF устанавливается в 1 при переносе из младшего полубайта результата во время сложения или при заеме в младший полубайт результата во время вычитания. Если же переноса или заема не было, AF устанавливается в 0. Флаг AF введен для выполнения десятичной настройки и обычно в других целях не используется.
3. Флаг знака SF устанавливается арифметическими и логическими инструкциями равным старшему (7-му или 15-му) биту результата. Для двоичных чисел со знаком SF будет равен 0 в случае положительного результата и 1 - в случае отрицательного (если нет переполнения). Значение флага SF может анализироваться после сложения или вычитания инструкциями условного перехода. Программы, выполняющие беззнаковые операции, обычно игнорируют SF, т.к. старший бит результата в этом случае интерпретируется как двоичная цифра, а не как знак.
4. Флаг нуля ZF устанавливается в 1, если результат арифметической или логической операции равен 0, и устанавливается в 0, если результат отличен от 0. Значение флага может анализироваться инструкциями условного перехода.
5. Флаг паритета PF устанавливается в 1, если младшие 8 бит результата арифметической или логической операции содержат четное число единиц, и устанавливается в 0, если число единиц нечетно. Флаг PF введен для совместимости с процессорами 8080/8085; он может также использоваться для контроля символов в коде ASCII на корректность паритета.
6. Флаг переполнения OF устанавливается в 1, если результат слишком велик для положительного числа или слишком мал для отрицательного и не помещается в операнд-приемник (не считая знаковый разряд). В противном случае значение OF -0. Состояние этого флага отражает наличие арифметического переполнения со знаком. Он может анализироваться инструкциями условного перехода или инструкцией INTO. В беззнаковых операциях OF обычно игнорируется.
2.3. Сложение.
ADD приемник,источник СЛОЖЕНИЕ БАЙТОВ ИЛИ СЛОВ
Арифметическая сумма 2-х операндов, которыми могут быть байты или слова, замещает операнд-приемник. Оба операнда могут содержать двоичные числа со знаком или без него (см. AAA и DAA). ADD модифицирует флаги AF, CF, OF, PF, SF и ZF.
ADC приемник,источник СЛОЖЕНИЕ С ПЕРЕНОСОМ
Эта инструкция выполняет арифметическую сумму своих операндов, добавляет 1, если установлен в 1 флаг CF, и помещает результат на место операнда-приемника. Оба операнда могут содержать двоичные числа со знаком или без него (см. AAA и DAA). ADC модифицирует флаги AF, CF, OF, PF, SF и ZF. Поскольку ADC использует перенос от предыдущей операции, она может применяться для сложения чисел длиннее 2 байтов.
INC приемник УВЕЛИЧЕНИЕ БАЙТА ИЛИ СЛОВА НА 1
К содержимому приемника прибавляется 1. Операнд может быть байтом или словом и рассматривается как двоичное число без знака (см. AAA и DAA). INC модифицирует флаги AF, OF, PF, SF и ZF и не влияет на CF.
AAA ASCII-НАСТРОЙКА ДЛЯ СЛОЖЕНИЯ
Эта инструкция преобразует содержимое регистра AL в корректное распакованное десятичное число; старший полубайт обнуляется. AAA модифицирует флаги AF и CF; состояния флагов OF, PF, SF и ZF после AAA не определены.
DAA ДЕСЯТИЧНАЯ НАСТРОЙКА ДЛЯ СЛОЖЕНИЯ
Эта инструкция корректирует результат предшествующего сложения 2-х правильных упакованных десятичных чисел, содержащийся в регистре AL. Содержимое AL преобразуется в пару корректных упакованных десятичных чисел. DAA модифицирует флаги AF, CF, PF, SF и ZF; состояние флага OF после DAA не определено.
2.4. Вычитание.
SUB приемник, источник ВЫЧИТАНИЕ БАЙТОВ ИЛИ СЛОВ
Содержимое источника вычитается из содержимого приемника, и результат помещается на место приемника. Операнды могут быть байтами или словами и содержать двоичные числа со знаком или без него (см. AAS и DAS). SUB модифицирует флаги AF, CF, OF, PF, SF и ZF.
SBB приемник, источник ВЫЧИТАНИЕ С ЗАЕМОМ
По этой инструкции содержимое источника вычитается из содержимого приемника, из результата вычитается еще 1, если установлен в 1 флаг CF, и окончательный результат помещается на место приемника. Оба операнда могут быть байтами или словами и содержать двоичные числа со знаком или без него (см. AAS и DAS). SBB модифицирует флаги AF, CF, OF, PF, SF и ZF. Поскольку SBB использует заем предыдущей операции, она может применяться для вычитания чисел длиннее 2 байтов.
DEC приемник УМЕНЬШЕНИЕ БАЙТА ИЛИ СЛОВА НА 1
Содержимое приемника уменьшается на 1. Приемник может быть байтом или словом. DEC модифицирует флаги AF, OF, PF, SF и ZF и не влияет на состояние CF.
NEG приемник ОТРИЦАНИЕ БАЙТА ИЛИ СЛОВА
По этой инструкции содержимое приемника, который может быть байтом или словом, вычитается из 0, и результат помещается на место приемника. Эта форма дополнения до 2 используется для изменения знака целого числа. Если операнд равен 0, его знак не изменяется. Попытка отрицания байта, содержащего -128, или слова, содержащего -32768, не изменяет операнд, но устанавливает в 1 флаг OF. NEG модифицирует флаги AF, CF, OF, PF, SF и ZF. Флаг CF всегда устанавливается в 1, исключая тот случай, когда операнд равен 0 (тогда и CF=0).
CMP приемник,источник СРАВНЕНИЕ БАЙТОВ ИЛИ СЛОВ
Инструкция CMP вычитает содержимое источника из содержимого приемника, но результат не возвращает. Операнды, которые могут быть байтами или словами, не изменяются, но модифицируются флаги AF, CF, OF, PF, SF и ZF, что может анализироваться последующими инструкциями условного перехода. Состояния этих флагов отражают отношение приемника к источнику. Например, если после CMP следует инструкция JG, переход произойдет, если содержимое приемника больше содержимого источника.
AAS ASCII-НАСТРОЙКА ДЛЯ ВЫЧИТАНИЯ
Эта инструкция преобразует находящийся в регистре AL результат предшествующей операции вычитания 2-х корректных десятичных распакованных чисел в корректное десятичное распакованное число, остающееся также в AL. Старший полубайт регистра AL обнуляется. AAS модифицирует флаги AF и CF; состояния флагов OF, PF и ZF после AAS не определены.
DAS ДЕСЯТИЧНАЯ НАСТРОЙКА ДЛЯ ВЫЧИТАНИЯ
Эта инструкция преобразует находящийся в регистре AL результат предшествующей операции вычитания 2-х корректных десятичных упакованных чисел в пару корректных десятичных упакованных цифр, остающихся также в AL. DAS модифицирует флаги AF, CF, PF, SF и ZF; состояние флага OF не определено.
2.5. Умножение.
MUL источник УМНОЖЕНИЕ БАЙТОВ ИЛИ СЛОВ БЕЗ ЗНАКА
Инструкция MUL выполняет беззнаковое умножение содержимых источника и аккумулятора. Если источник является байтом, в качестве аккумулятора используется регистр AL, а результат двойной длины помещается в регистры AH и AL. Если источник является словом, в качестве аккумулятора используется регистр AX, а результат двойной длины помещается в регистры DX и AX. Операнды рассматриваются как двоичные числа без знака (см. AAM). Если старшая половина результата (содержимое AH для источника-байта или содержимое DX для источника-слова) не равна 0, флаги CF и OF устанавливаются в 1, в противном случае - в 0. Когда CF и OF установлены в 1, это означает, что AH или DX содержит значимые цифры результата. Состояния флагов AF, PF, SF и ZF после MUL не определены.
IMUL источник ЦЕЛОЧИСЛЕННОЕ УМНОЖЕНИЕ БАЙТОВ ИЛИ СЛОВ
Инструкция IMUL выполняет умножение со знаком содержимых источника и аккумулятора. Если источник является байтом, в качестве аккумулятора используется регистр AL, а результат двойной длины помещается в регистры AH и AL. Если источник является словом, в качестве аккумулятора используется регистр AX, а результат двойной длины помещается в регистры DX и AX. Если старшая половина результата (содержимое AH для источника-байта или содержимое DX для источника-слова) не является расширением знака младшей половины, флаги CF и OF устанавливаются в 1, в противном случае - в 0. Когда CF и OF установлены в 1, это означает, что AH или DX содержит значимые цифры результата. Состояния флагов AF, PF, SF и ZF после IMUL не определены.
AAM ASCII-НАСТРОЙКА ДЛЯ УМНОЖЕНИЯ
Инструкция AAM корректирует результат предшествующей операции умножения 2-х корректных десятичных распакованных операндов. Корректное десятичное распакованное число, состоящее из 2-х цифр, извлекается из регистров AH и AL, и результат возвращается в регистры AH и AL. Старшие полубайты перемножаемых операндов должны быть обнулены, что необходимо AAM для формирования правильного результата. AAM модифицирует флаги PF, SF и ZF; состояния флагов AF, CF и OF после AAM не определены.
2.6. Деление.
DIV источник ДЕЛЕНИЕ БАЙТОВ ИЛИ СЛОВ БЕЗ ЗНАКА
Инструкция DIV выполняет беззнаковое деление содержимого аккумулятора (и его расширения) на содержимое источника. Если источник является байтом, предполагается, что делимое расположено в регистрах AH и AL. Частное остается в регистре AL, остаток - в регистре AH. Если источник является словом, предполагается, что делимое расположено в регистрах DX и AX. Частное в этом случае остается в регистре AX, остаток - в регистре DX. Если значение частного превосходит вместимость регистра-приемника (FFh для источника-байта или FFFFh для источника-слова), возникает ситуация "деление на 0" и генерируется прерывание с номером 0; частное и остаток в этом случае не определены.
Дробная часть частного отсекается. После DIV состояния флагов AF, CF, OF, PF, SF и ZF не определены.
IDIV источник ЦЕЛОЧИСЛЕННОЕ ДЕЛЕНИЕ БАЙТОВ ИЛИ СЛОВ
Инструкция IDIV выполняет деление со знаком содержимого аккумулятора (и его расширения) на содержимое источника. Если источник является байтом, предполагается, что делимое расположено в регистрах AH и AL. Частное остается в регистре AL, остаток - в регистре AH. Для такого деления максимально допустимое положительное частное равно 127 (7Fh), а минимально допустимое отрицательное частное равно -127 (81h). Если источник является словом, предполагается, что делимое расположено в регистрах DX и AX. Частное в этом случае остается в регистре AX, остаток - в регистре DX. Для такого деления значение частного может находиться в пределах от -32767 (8001h) до 32767 (7FFFh). Если частное положительно и превышает положительный максимум или отрицательно и меньше отрицательного минимума, генерируется прерывание с номером 0 (деление на 0); частное и остаток в этом случае не определены. Нецелочисленное частное округляется до целого числа (по направлению к 0). Остаток имеет тот же знак, что и делимое. После IDIV состояния флагов AF, CF, OF, ZF, PF и SF не определены.
AAD ASCII-НАСТРОЙКА ДЛЯ ДЕЛЕНИЯ
Инструкция AAD модифицирует числитель в регистре AL перед делением 2-х корректных десятичных распакованных операндов таким образом, чтобы частное от деления было также корректным десятичным распакованным числом. Для того, чтобы последующая инструкция DIV сформировала правильный результат, регистр AH должен содержать нули. Частное остается в регистре AL, остаток - в регистре AH; оба старших полубайта обнуляются. AAD модифицирует флаги PF, SF и ZF; состояния флагов AF, CF и OF после AAD не определены.
CBW ПРЕОБРАЗОВАНИЕ БАЙТА В СЛОВО
Инструкция CBW заполняет регистр AH битами, равными знаковому биту однобайтного числа в регистре AL. CBW на состояния флагов не влияет. Эта инструкция может использоваться для получения делимого двойного размера (слова) из результата предшествующей операции деления байтов.
CWD ПРЕОБРАЗОВАНИЕ СЛОВА В ДВОЙНОЕ СЛОВО
Инструкция CWD заполняет регистр DX битами, равными знаковому биту двухбайтного числа в регисте AX. CWD на состояния флагов не влияет. Эта инструкция может использоваться для получения делимого двойного размера (двойного слова) из результата предшествующей операции деления слов.
3. ЛИТЕРАТУРА:
1. Ассемблер для IBM PC (глава 13).
2. "Ассемблер: справочник" (издательство "Питер", 2000 год).
|