В Intel опкоды BCD представляют собой набор из шести x86 инструкций , которые работают с двоично - десятичными числами. Система счисления, используемая для представления чисел в процессорах x86 , равна 2. Это называется двоичной системой счисления . Однако процессоры x86 имеют ограниченную поддержку десятичной системы счисления .
Кроме того, часть x87 поддерживает уникальный 18-значный (10-байтовый) формат BCD, который можно загружать и сохранять из регистров с плавающей запятой , откуда могут выполняться обычные вычисления FP. [1]
Целочисленные инструкции BCD больше не поддерживаются в длинном режиме .
Использование [ править ]
Представление числа [ править ]
Числа BCD могут быть представлены в целочисленных регистрах двумя способами: упакованным десятичным и неупакованным десятичным.
- Упаковано (4 бита)
- В упакованном десятичном представлении десятичная цифра хранится в одном полубайте .
- Значения от 10 до 15 не используются. [2]
- Без упаковки (8 бит)
Обычно предполагается, что значения хранятся в младших 8 битах регистра, например AL.
Добавление [ править ]
Непосредственно можно добавлять только десятичные числа от 0 до 99 .
Сначала числа добавляются как обычно, используя add (или adc, если вам нужен флаг переноса ). Процессор установит флаг настройки, если сумма обоих младших полубайтов равна 16 или больше, и флаг переноса, если сумма обоих байтов равна 256 или больше.
Затем результат корректируется в зависимости от представления числа.
- Упакованы
- Результат корректируется с помощью daa (десятичная корректировка после добавления): если наименее значимый полубайт результата равен 10 или больше, или если установлен флаг настройки, то процессор добавляет 6 к результату и отбрасывает любое переполнение полубайта.
- Затем, если наиболее значимый полубайт результата равен 10 или больше, или если установлен флаг переноса, то процессор добавляет 96 (6 раз по 16) к результату и устанавливает флаг переноса. [2] [3]
- Распакованный
- Результат корректируется с использованием aaa (настройка ASCII после добавления): если наименее значимый полубайт результата равен 10 или больше, то процессор добавляет к нему 6 и отбрасывает любое переполнение полубайта и сохраняет его в младшем значащем байте.
- Увеличивается старший байт.
- Обратите внимание, что на этом этапе старший байт может не содержать допустимого десятичного числа. [2] [3]
Вычитание [ править ]
Непосредственно вычитаются только десятичные числа от 0 до 99 . Сначала числа вычитаются, как обычно, с помощью sub (или sbb, если вам нужен флаг переноса). Процессор установит флаг настройки, если заимствование произошло в младшем полубайте, и флаг переноса, если заимствование произошло в самом старшем полубайте.
- Упакованы
- Результат корректируется с помощью das (десятичная корректировка после вычитания): если младший полубайт результата равен 10 или больше, или если установлен флаг настройки, то процессор вычитает 6 из результата.
- Затем, если наиболее значимый полубайт результата равен 10 или больше, или если установлен флаг переноса, то процессор вычитает 96 (6 раз по 16) из результата и устанавливает флаг переноса. [2] [3]
- Распакованный
- Результат корректируется с помощью aas (настройка ASCII после вычитания): если младший полубайт результата равен 10 или больше, то процессор вычитает из него 6 и сохраняет его в младшем значащем байте.
- Уменьшается старший байт.
- Обратите внимание, что на этом этапе старший байт может не содержать допустимого десятичного числа. [2] [3]
Умножение [ править ]
Поддерживается только распакованное представление. Только две однозначных числа могут быть умножены .
Сначала цифры умножаются как обычно с помощью mul .
Затем результат корректируется с помощью aam (настройка ASCII для умножения): процессор делит результат на десять, сохраняя частное (только целую часть) в старшем байте результата, а остаток в младшем байте результата. . [2] [3]
Подразделение [ править ]
Поддерживается только распакованное представление. Операнды должны находиться в диапазоне от 0 до 99.
Сначала операнды преобразуются в нормальное двоичное представление с помощью aad (настройка ASCII перед делением): процессор преобразует числа, умножая старший байт на 10 и добавляя младший байт. Частное и остаток от деления получаются как обычно с использованием div и будут представлены в обычном двоичном представлении. [2] [3]
В x87 [ править ]
X87 сопроцессор имеет поддержку BCD в виде пары нагрузки (FBLD) и инструкции хранения и поп (FBSTP). Первый загружает 80-битное целое число BCD в FPU, а второй записывает значение FPU как 80-битное целое число в память. Внутри FPU значения хранятся как обычные числа с плавающей запятой x87 с расширенной точностью . В отличие от целочисленных версий, две инструкции остаются доступными в долгом режиме. [1]
80-битный формат делится на следующие:
79 | 78 .. 72 | 71 .. 0 |
---|---|---|
Знак | Не используется (0) | 18 упакованных цифр |
Существует специальное «неопределенное» значение, закодированное как FFFFC000000000000000h.
Заявление [ править ]
Десятичные числа с двоичным кодом (BCD) используются для хранения десятичных чисел, особенно в финансовом программном обеспечении. [2]
В опкоды упомянутые выше дают x86 элементарную поддержку BCD. [2]
Альтернативы [ править ]
Добавление чисел в двоично-десятичном формате с использованием этих кодов операций - сложная задача, требующая множества инструкций для сложения даже скромных чисел. Также может потребоваться большой объем памяти. [2] Если выполняются только целочисленные вычисления, тогда все целочисленные вычисления являются точными, поэтому основание системы счисления не имеет значения для точности. На процессоре x86 вычисления с двоичными числами обычно намного быстрее, чем те же вычисления с числами BCD. [2]
См. Также [ править ]
- Наборы команд обработки битов
Ссылки [ править ]
- ^ a b "4,7 BCD и упакованные целые числа BCD". Руководство разработчика программного обеспечения для архитектур Intel 64 и IA-32, Том 1: Базовая архитектура (PDF) . Версия 072. 1 . Корпорация Intel . 2020-05-27 [1997]. С. 3–2, 4-9–4-11 [4-10]. 253665-072US. Архивировано (PDF) из оригинала 06.08.2020 . Проверено 6 августа 2020 .
[…] При работе с целыми числами BCD в регистрах общего назначения значения BCD могут быть распакованы (одна цифра BCD на байт) или упакованы.(две цифры BCD на байт). Значение распакованного целого числа BCD - это двоичное значение младшего полубайта (биты с 0 по 3). Старший полубайт (биты с 4 по 7) может иметь любое значение во время сложения и вычитания, но должен быть равен нулю во время умножения и деления. Упакованные целые числа BCD позволяют содержать две цифры BCD в одном байте. Здесь цифра в старшем полубайте более значима, чем цифра в младшем полубайте. […] При работе с целыми числами BCD в регистрах данных x87 FPU значения BCD упаковываются в 80-битном формате и называются десятичными целыми числами. В этом формате первые 9 байтов содержат 18 цифр BCD, по 2 цифры на байт. Наименее значимая цифра содержится в нижней половине байта байта 0 иСамый старший разряд содержится в старшем полубайте байта 9. Самый старший бит байта 10 содержит знаковый бит (0 = положительный и 1 = отрицательный; биты с 0 по 6 байта 10 - это неважные биты) . Отрицательные десятичные целые числа не хранятся в форме дополнения до двух ; они отличаются от положительных десятичных целых чисел только знаковым битом. Диапазон десятичных целых чисел, которые могут быть закодированы в этом формате, составляет от –10 18 + 1 до 10 18 - 1. Формат десятичных целых чисел существует только в памяти. Когда десятичное целое число загружается в регистр данных x87 FPU, оно автоматически преобразуется в формат с плавающей запятой двойной расширенной точности.. Все десятичные целые числа точно представлены в формате двойной расширенной точности. […]
[1] - ^ a b c d e f g h i j k l Хайд, Рэндалл (сентябрь 2003 г.). Десятичная арифметика . Искусство программирования на языке ассемблера . Пресс без крахмала . Архивировано из оригинала на 2008-11-02 . Проверено 18 октября 2008 .
- ^ a b c d e f Том 2A: Справочник по набору команд, AM (PDF) . Руководство разработчика программного обеспечения для архитектур Intel 64 и IA-32 . 2А . Корпорация Intel . 2007-05-17. Архивировано из оригинального (PDF) 15 марта 2008 года . Проверено 27 июня 2007 .