Вопрос № 178135: Доброго времени суток дорогие эксперты. Требуется с помошью ТАСМ осуществить ввод знакового числа с клавиатуры и выод его на экран в требуемой форме представления. Использовать процедуры. Формат вводимого чила[/b[b]Формат вводимого ч...
Вопрос № 178288: В файле file.txt хранится следующая информация: DIR (команда MS DOS). Выполнить эту команду при запуске программы. (Для чтения файла использовать формулу 14)...
Вопрос № 178135:
Доброго времени суток дорогие эксперты.
Требуется с помошью ТАСМ осуществить ввод знакового числа с клавиатуры и выод его на экран в требуемой форме представления. Использовать процедуры.
Формат хранения этого числа: двоично - десятичное, 9-значное неупакованное.
Формат выводимого числа: вещественное с плавающей точкой.
Желательно по коду коментарии
и по яснее.
Хар-ки: 1)процессор intel core 2 solo CPU U3500 2)window vista home premium 32х разрядная 3)Turbo Assembler Version 4.1 в папке asm находится фаил TASM поэтому думаю он предпочтителен 4)вычисления производить в сопроцессоре
Отвечает Лысков Игорь Витальевич, Модератор :
Здравствуйте, Юдин Евгений Сергеевич. Вот Вам мой вариант решения задачи. 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 ;будем выводить в виде числа с плавающей
запятой с экспонентой
;вывод BCD числа в виде float ;si - адрес BCD ;cx - число информативных байт Print_BCD_Float proc dec cx ;число знаков после точки mov bx, cx ;смещение последнего информативного байта
test by
te 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
----- Удачи!
Ответ отправил: Лысков Игорь Витальевич, Модератор
Ответ отправлен: 12.05.2010, 10:16
Номер ответа: 261347 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 261347
на номер 1151 (Россия) |
Еще номера »
Вопрос № 178288:
В файле file.txt хранится следующая информация: DIR (команда MS DOS). Выполнить эту команду при запуске программы. (Для чтения файла использовать формулу 14)
Отвечает Лысков Игорь Витальевич, Модератор :
Здравствуйте, Джамалудинов Рустам. Вот Вам программа, читающая из файла file.txt в текущем каталоге первые три байта (там должно быть 'dir') Чтение выполняется при помощи функций, использующих FCB Затем выполняется command.com c параметром '/c dir'
Код:
;В файле
file.txt хранится следующая информация: DIR (команда MS DOS). ;Выполнить эту команду при запуске программы. ;(Для чтения файла использовать формулу 14) .model tiny .code .startup jmp start ;FCB для операции чтения файла FCB: db 03h ;диск C db 'file ' ;имя файла db 'txt' ;расширение dw 0 ;номер блока RecSize dw 0 ;размер записи dw 0,0 ;размер файла dw 0 ;дата db 10 dup (0) ;резерв CurR
ec dw 0 ;блоковый номер записи dw 0,0 ;файловый номер записи
;путь командного интерпретатора, которого будем запускать command db 'c:\windows\system32\command.com',0 ;строка параметров (первый байт - длина параметров) parm db 6,'/c ' ;сюда скопируем три первых байта (dir) из файла comstr db ' ',0dh ;блок EPB для запуска command.com EPB dw 0 comline dw 0, 0 FCB1 dw 0, 0 FCB2 dw 0, 0
sErrOpen db 'Open error$' sErrRead db 'Read
error$'
start: lea dx, FCB ;открываем файл mov ah, 0fh int 21h cmp al, 0 jne ErrorOpen ;проверка на ошибку
mov RecSize, 3 ;читаем 3 байта в DTA по адресу 80h mov ah, 14h ;dx - открытый FCB int 21h cmp al, 0 jne ErrorRead ;проверка на ошибку
mov ah, 10h ;закрываем FCB int 21h
;перед тем, как запустить command.com, ;необходимо урезать свою память mov bx, 1000h ;оставляем себе 64к
mov ah, 4ah int 21h
lea dx, command ;ds:dx - указатель на программу lea bx, EPB ;es:bx - указатель на EPB mov ax, 4b00h ;функция запуска программы int 21h Exit: mov ax, 4c00h ;выход в ДОС int 21h
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.