Для вывода двоичных значений из диапазона от 0 до
бесконечности используется способ, в основе которого лежит получение
остатков при последовательном делении исходного
значения на 10.
В основе алгоритма лежит положение о том, что цифры (...U2U,U0)
десятичного представления начиная с младшей получаются последовательным
делением исходного двоичного значения и на 10:
U0=u mod 10; U1Lu/10j mod 10; U2 41u/10j /10J mod 10 и т. д., до
тех пор пока после очередного деления делимое не окажется равным нулю:
L.-iLu/10j/10j..J=0 Здесь символы L и J обозначают целую часть частного,
округленного в меньшую
сторону.
Почему в отличие от алгоритмов ввода с консоли для обратного
преобразова ния нет такого разнообразия способов? Это объясняется
особенностью командь деления DIV микропроцессора, которая используется в
описанном выше алгорит ме для получения частного и остатка. Ее
требование к соотношению значенш делимого и делителя — размер частного
должен быть в два раза меньше делимо го. В противном случае возникает
исключение #0Е (ошибка деления) и програм ма аварийно завершается.
Исходя из этих условий нам ничего не остается, кроме как
воспользоватьс программой беззнакового деления значения размером N байт
на значение разме ром 1 байт. Она была рассмотрена в главе 1,
посвященной целочисленным ариф метическим операциям. Для удобства
использования эту программу мы офор мим в виде макрокоманды.
:prg06_08.asm - программа вывода целых десятичных чисел из диапазона О..оо.
;Вход: многобайтное двоичное число для преобразование в области памяти bin_dd.
:Выход: вывод десятичного числа из диапазона 0..<ю на экран.
:
div_unsign_N_l_I macro u.N.v.w.r
:div_unsign_N_l_I - макрокоманда деления N-разрядного беззнакового целого
:на одноразрядное число размером 1 байт (порядок следования байтов - младший байт
:по младшему адресу (Intel)). См. главу 1 и дискету
endm .data string db 10 dup (0) ;пусть максимальное десятичное число состоит из 10 цифр
len_string-$-string adr string dd string b1n~dd label BYTE "dd
Offffffffh 1 еп_Ы n_dd-$ - bi n_dd ten*db To remainder dw 0 .code
значение для преобразования должно быть в памяти
les di,adr_string строка с десятичными символами
eld обработка в прямом направлении
continue:
di v_unsign_N_l_I bin_dd.1en_bin_dd.ten.Ыn_dd.remainder
mov ax.remainder
or al.30h :преобразуем в символьное представление
stosb сохраняем в string очередную десятичную цифру
inccx {подсчитываем количество цифр
cmpbinjjd.0
jne continue :вывод на консоль с конца строки
mov ah,2
std
mov si .di
dec si ml: "lodsb
mov dl ,al
Int 21h
loop ml
В данной программе преобразованию подвергается значение в памяти. Причем мы в качестве исходного двоичного значения задали максимально возможное беззнаковое число размером в двойное слово. Результат преобразования — 4 294 967 295, что полностью сходится с ожидаемым десятичным значением. Но задавать исходные значения в памяти не всегда удобно, хотелось бы, чтобы можно было подвергать преобразованию значения прямо из регистров процессора. Для такого типа преобразований (значений в регистрах процессора) лучше подойдет способ с использованием сопроцессора. Рассмотрим его.