Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Чемпионы рейтинга экспертов в этой рассылке

Boriss
Статус: Академик
Рейтинг: 2291
∙ повысить рейтинг »
_Ayl_
Статус: Практикант
Рейтинг: 1829
∙ повысить рейтинг »
vladisslav
Статус: 6-й класс
Рейтинг: 1235
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И ПО / Программирование / Assembler (Ассемблер)

Номер выпуска:1337
Дата выхода:14.05.2010, 12:00
Администратор рассылки:Лысков Игорь Витальевич, Модератор
Подписчиков / экспертов:277 / 60
Вопросов / ответов:2 / 2
IRC-канал по теме:#assembler

Вопрос № 178135: Доброго времени суток дорогие эксперты. Требуется с помошью ТАСМ осуществить ввод знакового числа с клавиатуры и выод его на экран в требуемой форме представления. Использовать процедуры. Формат вводимого чила[/b[b]Формат вводимого ч...


Вопрос № 178288: В файле file.txt хранится следующая информация: DIR (команда MS DOS). Выполнить эту команду при запуске программы. (Для чтения файла использовать формулу 14)...

Вопрос № 178135:

Доброго времени суток дорогие эксперты.

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

Формат вводимого чила[/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, 08:16
Вопрос задал: Юдин Евгений Сергеевич, 1-й класс
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич, Модератор :
Здравствуйте, Юдин Евгений Сергеевич.
Вот Вам мой вариант решения задачи.
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 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 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Вопрос № 178288:

    В файле file.txt хранится следующая информация: DIR (команда MS DOS). Выполнить эту команду при запуске программы. (Для чтения файла использовать формулу 14)

    Отправлен: 08.05.2010, 19:01
    Вопрос задал: Джамалудинов Рустам, Посетитель
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич, Модератор :
    Здравствуйте, Джамалудинов Рустам.
    Вот Вам программа, читающая из файла 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

    mov si, 80h ;адрес DTA (команда из файла)
    lea di, comstr ;место в строке параметров
    mov cx, 3 ;длина - 3 байта
    rep movsb ;копируем

    mov comline, offset parm ;вставляем в EPB длинный указатель
    mov comline+2, cs ;на строку параметров

    lea dx, command ;ds:dx - указатель на программу
    lea bx, EPB ;es:bx - указатель на EPB
    mov ax, 4b00h ;функция запуска программы
    int 21h
    Exit:
    mov ax, 4c00h ;выход в ДОС
    int 21h

    ;обработка ошибок
    ErrorOpen:
    lea dx, sErrOpen
    jmp Print
    ErrorRead:
    lea dx, sErrRead
    Print:
    mov ah, 9
    int 21h
    jmp Exit

    end

    -----
    Удачи!

    Ответ отправил: Лысков Игорь Витальевич, Модератор
    Ответ отправлен: 09.05.2010, 02:45
    Номер ответа: 261294
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru
    Абонент Skype: igorlyskov

    Оценка ответа: 5
    Комментарий к оценке:
    мы пользуемся немного другими командами, но видимо это уже наша вина. Спасибо за помощь, выручили!

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 261294 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.14 от 03.03.2010

    В избранное