Консультация № 178135
01.05.2010, 08:16
0.00 руб.
0 13 1
Доброго времени суток дорогие эксперты.

Требуется с помошью ТАСМ осуществить ввод знакового числа с клавиатуры и выод его на экран в требуемой форме представления. Использовать процедуры.

Формат вводимого чила[/b[b]Формат вводимого чила] : Шестнадцатиричное 8 значное

Формат хранения этого числа: двоично - десятичное, 9-значное неупакованное.

Формат выводимого числа: вещественное с плавающей точкой.

Желательно по коду коментарии и по яснее.

Хар-ки:
1)процессор intel core 2 solo CPU U3500
2)window vista home premium 32х разрядная
3)Turbo Assembler Version 4.1 в папке asm находится фаил TASM поэтому думаю он предпочтителен
4)вычисления производить в сопроцессоре

Обсуждение

Неизвестный
01.05.2010, 19:42
общий
(Много написали: повторю) То есть:
1) нужно ввести вещественное (судя по третьему пункту) число в шестнадцатиричной форме представления? Какие формы допустимы: с фиксированной запятой? С плавающей запятой? Экспоненциальное?
2) Хранить в другом формате. И опять формат числа как и в предыдущем случае - какой? (не BCD, а какой формат: как у double (смещенный показатель, нормированная мантисса)? Или отдельный полубайт (тетраду) использовать для десятичной точки?)
3) Выводить в какой системе счисления?
Неизвестный
03.05.2010, 10:41
общий
Цитата: 422
(Много написали: повторю) То есть:
1) нужно ввести вещественное (судя по третьему пункту) число в шестнадцатиричной форме представления? Какие формы допустимы: с фиксированной запятой? С плавающей запятой? Экспоненциальное?
2) Хранить в другом формате. И опять формат числа как и в предыдущем случае - какой? (не BCD, а какой формат: как у double (смещенный показатель, нормированная мантисса)? Или отдельный полубайт (тетраду) использовать для десятичной точки?)
3) Выводить в какой системе счисления?


1)Нужно ввести 8-значное число в шестнадцатиричной форме представления. Допустимы любые формы, так как нет четкого определения какое число ( оно должно главное быть шестнадцатиричным и 8-значным одновременно)
2)формат числа десятичная форма представления 9-значное и неупакованное(число не указано каким должно быть - желательно предусмотреть и тот и тот ввод)
3)Выводить его вещественным с плавающей точкой в десятичной или 16 - ричной форме(пусть выводится на экран и то и то-конкретной ясности в условиях нет)
Неизвестный
03.05.2010, 17:40
общий
Хм. Если выводить вещественным, то и вводить вещественным надо. Иначе смысла нет: вводить целым, а выводить вещественным
Неизвестный
04.05.2010, 08:22
общий
А как вы представляете Шестнадцатиричное 8 значное например 0FFFFFFFFh, то что будет такое двоично - десятичное, 9-значное неупакованное.
Неизвестный
04.05.2010, 09:29
общий
Airyashov:
Я полагаю, что ограничение на 8-значность касается только ввода и только в шестнадцатиричной форме. Более того: десятичная точка (формат с плавающей запятой) добавляет 9-й полубайт. Я уже попробовал в сопроцессоре: нормально формируется вещественное число.
давно
Посетитель
7438
7205
05.05.2010, 17:59
общий
Boriss:
Доброго времени суток
Программку писать будете?
Кстати, шестнадцатиричное 8-значное даст больше чем 9 знаков: 7fffffffh = 2147483647 (10 знаков, а не 9!)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
05.05.2010, 18:03
общий
Boriss:
Если выводить вещественным, то и вводить вещественным надо. Иначе смысла нет: вводить целым, а выводить вещественным
Смысл в отработке форм представления...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
06.05.2010, 14:18
общий
Что-то, казалось мне, что срок подходит - было продление?
Да, осталось оформить, проверить... Все никак не возьмусь: появилась возможность взаимодействовать с заводом, связи с которым, из-за лихих чубаевских, было, померли. Но требуется кучу бумаг написать, как всегда.
Насчет размера: +1 полубайт = точка. Так что нужно dq (что и сделано )
Да, задание "из тех" - ох, не люблю таких умников, которые из N-места вытаскивают никчемные задания, но с очень умным видом. Имею ввиду, конечно, не спрашивающего
Неизвестный
06.05.2010, 14:20
общий
Цитата: Лысков Игорь Витальевич
Boriss:
© Цитата:
Если выводить вещественным, то и вводить вещественным надо. Иначе смысла нет: вводить целым, а выводить вещественным

Смысл в отработке форм представления...


Да. Смысл в том что вводим одно представление, храним другое, а выводим 3е.
Неизвестный
06.05.2010, 14:24
общий
Согласен с обоими (как Шариков), но использую только представление с плавающей запятой (не использую экспоненциальную!). Так?
давно
Посетитель
7438
7205
06.05.2010, 14:45
общий
Boriss:
Имхо, именно, "с плавающей запятой", которая для целого числа, кстати, будет в конце (0 десятых)...
Кстати, вывод легко можно организовать с помощью FBSTP...
PS Продлил, а как же...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
06.05.2010, 14:57
общий
Думал только попробовать, но, возможно будет работать только для целых (не проблема - запомнить точку, и все )
давно
Посетитель
7438
7205
12.05.2010, 10:16
общий
это ответ
Здравствуйте, Юдин Евгений Сергеевич.
Вот Вам мой вариант решения задачи.
1) Вводим hex-строку (на корректность символов не проверяется!)
2) Преобразовываем в неупакованное BCD-число. Только длина не 9 знаков, а 10, т.к. длина максимального числа 7fffffffh = 2147483647 равна 10 символам!
Кроме того, порядок знаков - младший первый, знак помечаем старшим битом в самом старшем (последнем) байте
3) Выводим в виде вещественного числа с экспонентой. Т.е., один знак - целая часть, остальные за точкой и порядок за буковкой 'e'
Код:

.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
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа