(Много написали: повторю) То есть:
1) нужно ввести вещественное (судя по третьему пункту) число в шестнадцатиричной форме представления? Какие формы допустимы: с фиксированной запятой? С плавающей запятой? Экспоненциальное?
2) Хранить в другом формате. И опять формат числа как и в предыдущем случае - какой? (не BCD, а какой формат: как у double (смещенный показатель, нормированная мантисса)? Или отдельный полубайт (тетраду) использовать для десятичной точки?)
3) Выводить в какой системе счисления?
Если выводить вещественным, то и вводить вещественным надо. Иначе смысла нет: вводить целым, а выводить вещественным
Boriss:
© Цитата:
Если выводить вещественным, то и вводить вещественным надо. Иначе смысла нет: вводить целым, а выводить вещественным
Смысл в отработке форм представления...
.model tiny ;делаем com-файл
.286
locals @@ ;все метки, начинающиеся с @@ - локальные
.code
.startup ;точка входа
lea dx, sPrompt
mov ah, 9
int 21h ;подсказка для ввода строки с hex-числом
lea dx, max
mov ah, 0ah
int 21h ;вводим hex
lea si, string ;адрес строки
call htoi ;преобразуем в bin
;результат в dx:ax
lea di, BCD ;адрес 10 байт BCD-числа
call int_BCD_signed ;преобразуем в неупакованный BCD формат
;младший первым, знак помечается старшим битом
;старшего(последнего)байта
;на выходе: di - адрес, cx - число информативных байт
lea dx, sFloat
mov ah, 9
int 21h ;будем выводить в виде числа с плавающей запятой с экспонентой
lea si, BCD ;адрес BCD
call Print_BCD_Float ;выводим
lea dx, sPress
mov ah, 9
int 21h ;press any key
mov ah, 0
int 16h ;ждем клавишу
.exit 0 ;mov ax,4c00h
;int 21h
;вывод BCD числа в виде float
;si - адрес BCD
;cx - число информативных байт
Print_BCD_Float proc
dec cx ;число знаков после точки
mov bx, cx ;смещение последнего информативного байта
test byte ptr [si+9], 80h ;проверим знак числа
jz @@num ;положительное - на вывод
mov al, '-' ;для отрицательного сначала выведем минус
int 29h
@@num:
call Pr_Dig ;старший байт - целая часть
mov al, '.'
int 29h ;точка
push cx ;сохраним количество остальных знаков для вывода порядка
jcxz @@exp ;если был всего один байт, то сразу на вывод порядка
@@loop:
call Pr_Dig ;выведем остальные цифры
loop @@loop
@@exp:
mov al, 'e' ;буковка 'e'
int 29h
mov al, '+' ;'+' - положительный порядок
int 29h
mov al, '0' ;у нас максимум 1 цифра, дополним до двух нулем
int 29h
pop ax ;порядок
or al, '0' ;превратим в символ
int 29h
ret
Print_BCD_Float endp
;получение и вывод очередного байта из строки BCD по адресу [si+bx]
Pr_Dig proc
mov al, [si+bx]
dec bx ;перемещаемся к началу
and al, 7fh ;сбросим бит знака (хотя реально может быть только у одного)
or al, '0' ;в символ
int 29h
ret
Pr_Dig endp
;преобразуем hex-строку [si], заканчивающейся на 0dh, в int
;результат в dx:ax
htoi proc
xor cx, cx
xor bx, bx ;bx:cx
@@loop:
lodsb ;очередной
cmp al, 0dh ;проверим на конец
je @@ret
mov ah, ch ;получим старшую тетраду старшего байта младшего слова
shr ah, 4
shl bx, 4 ;сдвинем старшее слово на одну hex-цифру влево
or bl, ah ;вставим старшую hex-цифру младшего слова как младшую
shl cx, 4 ;сдвинем младшее слово на одну hex-цифру влево
;получим из символа hex-цифру
or al, 20h ;чтобы буковки 'a'-'f' стали маленькими (на цифры не влияет)
cmp al, 'a' ;буковка?
jb @@dig09 ;для цифры просто оставляем младшую тетраду
sub al, 'a'-10 ;для буквы делаем 0ah-0fh
@@dig09:
and al, 0fh ;оставляем только младшую тетраду
or cl, al ;и вставляем на место младшей hex-цифры нашего int-а
jmp @@loop
@@ret:
mov ax, cx ;результат
mov dx, bx
ret
htoi endp
;преобразуем знаковый int dx:ax в знаковое BCD число по адресу [di]
int_BCD_signed proc
push ax dx di ;сохраним число и адрес
push di ax ;обнулим область
mov cx, 5 ;5 слов = 10 байт
xor ax, ax
rep stosw
pop ax di
xor si, si ;запомним знак, si=0 > 0
or dx, dx ;проверим знак
jns @@no_sign
or si, 80h ;маска для отрицательного числа
not ax ;изменение знака на +
not dx
add ax, 1
adc dx, 0
@@no_sign:
CALL int_BCD ;выводим положительное беззнаковое число
mov cx, di ;cx=di - адрес за последним выведенным байтом
mov dx, si ;знак
pop di ;восстановим адрес начала BCD
or [di+9], dl ;вставим знак в старший (последний) байт BCD числа
sub cx, di ;число сформированных байт
pop dx ax
ret
int_BCD_signed endp
;Вывод беззнакового двойного слова из DX:AX
;просто делением на 10 не получится, возможно переполнение
;переполнение возможно и при делении на 10000
;поэтому делим на 100000, причем в два этапа:
;сначала на 50000 (что помещается в слово), затем на 2
;затем выводим частное от деления и остаток (5-значное цисло!)
;разные ньюансы смотрим по ходу...
int_BCD proc
push si cx dx bx ax
xor cx, cx ;старшее слово остатка от деления на 100000,
; т.к. макс значение 99999 не помещается в слово!
mov bx, 50000 ;делим сначала на 50000
div bx
shr ax, 1 ;и на 2
jnc @@1 ;если нет переноса, то остаток < 50000 !
add dx, 50000 ;добавим к остатку 50000 !
adc cx, 0 ;и учтем перенос !
@@1:
xor si, si ;количество выводимых цифр в остатке.
;0 - выводим остаток, сколько есть значащих цифр
;5 - если есть частное от деления на 100000,
; то у остатка должно быть обязательно 5 значащих цифр!
test ax, ax ;проверим частное от деления на 100000
jz @@2 ;выводим остаток как есть
mov si, 5 ;или 5 обязательных цифр остатка!
@@2: ;сначала выведем младшие 5 (или меньше) цифры
push ax ;сохраним частное
mov ax, dx ;остаток в dx:ax
mov dx, cx
call write5DigDEC ;выводим
pop ax ;восстановим частное
test ax, ax
jz @@3 ;если 0, то на выход
call writeWordDEC ;выводим частное, как слово
@@3:
pop ax bx dx cx si
ret
int_BCD endp
;вывод на экран 5 дес цифр в DX:AX, воспринимается как беззнаковое
;SI - количество обязательных цифр
write5DigDEC proc
mov bx, 10 ;будем делить на 10
xor cx, cx ;счетчик цифр
@@1:
div bx ;делим dx:ax на bx
mov [di], dl ;сохраняем остаток от деления
inc di ; как очередную младшую цифру
xor dx, dx ;подготавливаемся к последующему делению
inc cx ;считаем цифры
or ax, ax ;есть еще разряды?
jnz @@1 ;пока не разложим на цифры
mov al, 0 ;выведем незначащие нули!
mov dx, cx ;число полученных цифр
@@2:
cmp dx, si ;сравним с максимальным
jae @@3 ;для 0 сразу уходим, для 5 - пока не добавим
mov [di], al ;выводим разряд
inc di
inc dx ;необходимое количество незначащих нулей
jmp @@2
@@3:
ret
write5DigDEC endp
; вывод на экран слова в AX, воспринимается как беззнаковое
writeWordDEC proc
push dx bx ax
mov bx, 10 ;делим на 10
@@1:
xor dx, dx ;подготавливаемся к делению
div bx ;делим dx:ax на bx
mov [di], dl ;очередной разряд
inc di
or ax, ax ;есть еще разряды?
jnz @@1 ;пока не разложим на цифры
pop ax bx dx
ret
writeWordDEC endp
.data
sPrompt db 'Enter HEX number: $'
sFloat db 0dh,0ah,'Float = $'
sPress db 0dh,0ah,'Press any key$'
max db 9 ;для ввода максимум 8 hex-цифр + 0dh
db 0
string db 9 dup (?)
BCD dt ? ;10 байт BCD
end
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.