Ввод чисел с консоли. Преобразование целых десятичных чисел.
Приведенная программа преобразует любое значение из диапазона 0..1018-!. Интересно отметить количественное значение максимальной двоичной величины, соответствующее верхней границе диапазона, – это +0de0b6b3a763ffffl6. Запомните его, оно пригодится нам при рассмотрении обратного преобразования Для вывода на консоль – из двоичного в десятичное представление. Извлечь значение нужной разрядности можно, если ввести директивой label соответствующие идентификаторы в исходный текст программы (что и сделано в нашем сегменте кода):
string_bin_byte label byte string_bin_word label word string_bin_word label word string_bin_dword label dword
Ввод целых десятичных чисел из диапазона 0..до бесконечности
Для преобразования десятичного числа произвольной разрядности из символьного представления в двоичное потрудиться придется несколько больше. Основа для этой работы была создана в материале, посвященном арифметическим операциям для чисел произвольной разрядности. Поэтому наши действия при разработке программы преобразования напомнит игру с конструктором, когда из готовых компонент будет создаваться новый продукт.
Исходными компонентами программы преобразования десятичного числа произвольной разрядности из символьного представления в двоичное будут являться макрокоманда умножения N-байтного числа на число размером М байт и программа сложения чисел размером N байт без учета знака. Алгоритм вычисления двоичного эквивалента будет таким же, как рассмотренный выше, – вычисление полинома по схеме Горнера. Ниже приведен вариант реализующей его программы. Расположение байтов результата – по схеме, естественной для микропроцессоров Intel, то есть младший байт располагается по младшему адресу.
:prg06_04.asm – программа ввода целых десятичных чисел из диапазона 0..∞. ;Вход: ввод с клавиатуры числа в десятичной системе счисления длиной до 20 цифр. ;Выход: двоичное число – результат преобразования в области памяти string_bin. :см. описание макрокоманд add_unsign_N_l и mul_unsign_NM в главе 1 add_unsIgn_N_lmacro summand_l, summand_2, N endm mul_unsign_NM macro u.i.v.j.w endm.data string db 22 dup (0) максимальное число состоит из 20 цифр (22 – с учетом OdOah) len_string-$-string tendd 10 string_bindb 10 dup (0) максимальная длина двоичного числа – 10 байт len_stri ng_bi n-$-stri ng_bi n carry db 0:перенос сложения последних байтов adr_string_bindd string_bin string_bin_w db len_string_bin+l dup (0) ;результат умножения для макроса ;mul_unsign_NM = len_string_bin+l байт len_string_bin_w =$-string_bin_w adr_string_bin_w dd string_bin_w k db 0:перенос 0 < k < 255 b dw lOOh;размер машинного слова .code movbx.O стандартный дескриптор – клавиатура mov cx.len_string lea dx.string;формируем указатель на строку string movah,3fh:номер функции DOS int 21h jc exit:переход в случае ошибки:в регистре AL – количество действительно введенных десятичных цифр mov ecx.eax sub есх.2 корректируем счетчик цикла (чтобы не учитывать OdOah. вводимые 3fh) jcxz $+4:число не было введено jmp $+5 jmp exit cont_l:dec ecx;не умножать на 10 последнюю цифру числа jcxz $+4 юднозначное число tjmp S+5 jmp m2 lea si.string;формируем указатель на строку string хог еах.еах:еах: = 0 ml: хоr edx.edx mov dl.[si] and dl.Ofh преобразуем ASCI I › BCD add_unsign_N_lstring_bin.dl .len_string_bin:. умножаем на 10 mul_unsign_NM string_bin .len_string_bin.ten,l .string_bin_w:копируем string bin_w в string_bin eld push si push ex Ids si.adr_sthng_bin_w lesdi.adr_string_bin mov cx.len_string_bin_w repmovsb pop ex pop si inc si dec ex jcxm2 ' jmp ml m2: mov dl.[si] and dl.Ofh : add_unsign_N_lstring_bin.dl, len_string_bin : результат преобразования – в строке string_bin
Одно из направлений совершенствования этой программы – динамическое выделение памяти для всех чисел с неизвестной длиной. Необходимо заметить, что способ преобразования длинных чисел универсален – его можно использовать и для преобразования значений, которые укладываются в представимые в микропроцессоре диапазоны типов данных.