Вывод целых десятичных чисел
Вывод целых десятичных чисел из диапазона 0..99
Выше упоминалось, что для значений из диапазона 0..99 взаимное преобразование между символьной десятичной и двоичной формами может производиться командами умножения и деления двоично-десятичных (BCD-чисел) – ААМ и AAD.
;prg06_07.asm – ввод с консоли десятичного числа из диапазона 0..99 :и обратный его вывод на консоль. buf_Oahstruc len_bufdb 3;длина buf_0ah len_in db 0.действительная длина введенного слова (без учета Odh) bufjn db 3 dup (20h):буфер для ввода (с учетом Odh) ends.data bufbuf_0ah<> adr_bufdd buf '.code :вводим 2 символа с клавиатуры, контроль на допустимые значения не делаем ldsdx.adr_buf mov ah.Oah int 21h хоr ах.ах emp buf.len_in,2.-сколько чисел введено реально? jne ml mov ah.buf.bufjn ml: mov al.buf,buf_in+l andax.OfOfh преобразование в неупакованное десятичное представление add:в AL двоичный эквивалент исходного двузначного десятичного значения ;вывод на консоль содержимого AL аат mov dx.ax or dx.03030h rol dx.8:выводим старшую цифру mov ah,2 int 21h rol dx.8:выводим младшую цифру int 21h
Для преобразования с целью последующего вывода на консоль больших двоичных значений можно использовать два способа: путем деления по модулю 10 (диапазон значений не ограничен) и с помощью сопроцессора (0..1018-1).
Вывод целых десятичных чисел из диапазона от 0 до бесконечности
Для вывода двоичных значений из диапазона от 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, что полностью сходится с ожидаемым десятичным значением. Но задавать исходные значения в памяти не всегда удобно, хотелось бы, чтобы можно было подвергать преобразованию значения прямо из регистров процессора. Для такого типа преобразований (значений в регистрах процессора) лучше подойдет способ с использованием сопроцессора. Рассмотрим его.