Иллюстрированный самоучитель по задачам и примерам Assembler

Вывод целых десятичных чисел

Вывод целых десятичных чисел из диапазона 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, что полностью сходится с ожидаемым десятичным значением. Но задавать исходные значения в памяти не всегда удобно, хотелось бы, чтобы можно было подвергать преобразованию значения прямо из регистров процессора. Для такого типа преобразований (значений в регистрах процессора) лучше подойдет способ с использованием сопроцессора. Рассмотрим его.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.