Второй способ преобразования десятичных чисел хотя и выглядит несколько экзотически, вполне работоспособен. Данный способ предполагает использование особенностей некоторых команд сопроцессора. В материале урока 19 «Архитектура и программирование сопроцессора» учебника мы перечисляли форматы данных, которые поддерживает сопроцессор. Перечислим их еще раз:

  • двоичные целые числа в трех форматах — 16, 32 и 64 бита;
  • упакованные целые десятичные (BCD) числа — максимальная длина -18 упакованных десятичных цифр (9 байт);
  • вещественные числа в трех форматах — коротком (32 бита), длинном (64 бита), расширенном (80 бит).

Для нас интерес представляют форматы целых двоичных и упакованных десятичных (BCD) чисел, а также команды обмена этими значениями с вершиной сопроцессора. Процесс преобразования десятичного целого числа, вводимого с клавиатуры, показан в программе ниже. Необходимо отметить, что этот способ преобразования позволяет расширить диапазон значений 0..999 999 999 999 999 999.

:prg06_03.asm - программа ввода целых десятичных чисел из диапазона
:0..999 999 999 999 999 999 и преобразования их в эквивалентное двоичное представление.
;Вход: ввод с клавиатуры числа в десятичной системе счисления
:в диапазоне значений 0..999 999 999 999 999 999.
:Выход: двоичное число-результат преобразования в области памяти stnng_bin.
.data
db 0 :барьер. если введенное количество цифр нечетно string db 20 dup (0) максимальное исходное число состоит из 18 цифр (20 - с учетом
Od0ah)
len_string=$-string adr_string dd string
string_pack dt 0 :сюда упаковывается исходное значение
len_string_pack=$-string_pack adr_string_pack dd string_pack результат - двоичное значение различной разрядности:

string_bin_byte label byte
string_bin_word label word
string_bin_word label word
string_bin_dword label dword

string_bindq 0 ;поле для результата - эквивалентного двоичного представления

--------вводим с экрана----------------............-----
movbx.O стандартный дескриптор - клавиатура
movcx. len_str"ing
lea dx.string :формируем указатель на строку string
movah.3fh :номер функции DOS
int 21h
jc exit ;переход в случае ошибки
;в регистре AL - количество действительно введенных десятичных цифр :преобразуем строку с десятичными числами в ее двоичный эквивалент
mov ex.ax
subcx,2 корректируем счетчик цикла (чтобы не учитывать OdOah, вводимые 3fh)
jeexz exit :число не было введено
Ids si ,adr_string
add si,cx
dec si указатель на последнюю введенную десятичную цифру
les di.adr_string_pack ml: std :флаг df=l - работаем со строкой string, начиная с ее конца
хог ах.ах
lodsb
and al. Of h
shl ax.8
lodsb
shl al .4
add al.ah :в AL две очередные упакованные цифры
eld :флаг df-1 - работаем со строкой string_pack. начиная с ее начала
stosb
sub ex.2
emp ex. 0
J9 ml ;конец преобразования в упакованное представление
fI nit инициализируем сопроцессор ;теперь преобразуем в эквивалентное двоичное представление:
fbld string_pack :помещаем в стек сопроцессора 'fistp string_bin ;и извлекаем эквивалентное двоичное представление в поле string_bin

Приведенная программа преобразует любое значение из диапазона 0..1018-!. Интересно отметить количественное значение максимальной двоичной величины, соответствующее верхней границе диапазона, — это +0de0b6b3a763ffffl6. Запомните его, оно пригодится нам при рассмотрении обратного преобразования Для вывода на консоль — из двоичного в десятичное представление. Извлечь значение нужной разрядности можно, если ввести директивой label соответствующие идентификаторы в исходный текст программы (что и сделано в нашем сегменте кода):

string_bin_byte label byte
string_bin_word label word
string_bin_word label word
string_bin_dword label dword