Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Чемпионы рейтинга экспертов в этой рассылке Номер выпуска: | 1360 | Дата выхода: | 17.06.2010, 03:00 | Администратор рассылки: | Лысков Игорь Витальевич, Старший модератор | Подписчиков / экспертов: | 235 / 63 | Вопросов / ответов: | 1 / 2 | IRC-канал по теме: | #assembler | Вопрос № 179054: Доброго времени суток, уважаемые эксперты! Помогите, пожалуйста решить ещё одну задачу для ТАСМ по теме "Прерывания": С клавиатуры вводится последовательность цифр. Нужно выдать на экран разность каждой предыдущей и последующей цифры,... Вопрос № 179054: Доброго времени суток, уважаемые эксперты! Помогите, пожалуйста решить ещё одну задачу для ТАСМ по теме "Прерывания": С клавиатуры вводится последовательность цифр. Нужно выдать на экран разность каждой предыдущей и последующей цифры, если эта разность отрицательное число. Отправлен: 12.06.2010, 02:46 Вопрос задал: Даниил Цветков, Студент Всего ответов: 2 Страница вопроса » Отвечает Лысков Игорь Витальевич, Старший модератор : Здравствуйте, Даниил Цветков. Программа:Код: .model small .data ;Структура для ввода строки по функции 0ah max db 128 ;макс размер буфера count db 0 ;реальный размер string db 129 dup (0) ;буфер
;сообщения sString db 'Enter number string: $' sSub db 0dh,0ah sSub1 db 32 dup (0) sAny db 0dh,0ah,'Press any key$'
.code .286 .startup ;DS=@DATA mov ax, @DATA mov es, ax ;нужно проинициализировать также и регистр ES
lea dx, sString ;приглашение ввести строку mov ah, 9 int 21h
lea dx, max ;вводим строку mov ah, 0ah int 21h
xor cx, cx mov cl, count ;количество символов sub cx, 2 ;проходов на 2 меньше jle finish ;если <3, то на выход lea si, string ;строка num_loop: lodsb ;al=очередной символ, si=si+1 sub al, [si+1] ;отнимаем символ на 2 вперед jge next ;если >= 0 , то на следующий neg al ;разность отрицательная, мозьмем модуль числа mov ah, 0 ;байт в слово push ax ;сохраним
lea di, sSub1 ;сформируем строку mov al, [si-1] ;предыдущая цифра stosb mov al, '-' ;минус stosb mov al, [si+1] ;последующая цифра stosb mov ax, '= ' ;' =' stosw stosb ;' ' mov al, '-' ;'-', число отрицательное! stosb pop ax ;разность call PrDec ;сформируем числовую строку mov al, '$' ;закроем строку для 9-й функции stosb lea dx, sSub ;выведем mov ah, 9 int 21h next: loop num_loop ;по всем finish: lea dx, sAny ;выводим 'Press any key' mov ah, 9 int 21h
mov ah, 8 ;ждем нажатия int 21h mov ax, 4c00h ;завершаемся int 21h
;выведем десятичное число PrDec proc push cx xor cx, cx ;количество цифр mov bx, 10 ;будем делить на 10 div_loop: xor dx, dx ;подготавливаемся к делению div bx ;dx:ax / bx push dx ;сохраним остаток - очередную младшую цифру inc cx ;считаем цифры test ax, ax ;есть еще? jnz div_loop out_loop: ;выводим в обратном порядке pop ax ;извлечем из стека or al, '0' ;превратим в символ stosb ;сохраним в буфере очередной символ-цифру loop out_loop ;по всем pop cx ret PrDec endp
end
Вводим всю строку сразу с помощью функции 0ah Символы не проверяются на цифры! Предполагается корректный ввод. Затем в цикле считаются разности между "предыдущей и последующей цифрой", и если она отрицательная, то выводится строка, в которой выводятся цифры, которые отн имаются и разность
Еще одно решение, аналогичное первому, но с функциями BIOS-а. Дополнительно проверяем на ввод только цифр.
Код: .model small .data ;Структура для ввода строки max db 128 ;макс размер буфера count db 0 ;реальный размер string db 129 dup (0) ;буфер
;сообщения sString db 'Enter number string: ',0 sSub db 0dh,0ah sSub1 db 32 dup (0) sAny db 0dh,0ah,'Press any key',0
.code .286 .startup ;DS=@DATA mov ax, @DATA mov es, ax ;нужно проинициализировать также и регистр ES
lea si, sString ;приглашение ввести строку call PrString
lea di, max ;вводим строку call GetStr ing
xor cx, cx mov cl, count ;количество символов sub cx, 2 ;проходов на 2 меньше jle finish ;если <3, то на выхо д lea si, string ;строка num_loop: lodsb ;al=очередной символ, si=si+1 sub al, [si+1] ;отнимаем символ на 2 вперед jge next ;если >= 0 , то на следующий neg al ;разность отрицательная, мозьмем модуль числа mov ah, 0 ;байт в слово push ax ;сохраним
lea di, sSub1 ;сформируем строку mov al, [si-1] ;предыдущая цифра stosb mov al, '-' ;минус stosb mov al, [si+1] ;последующая цифра stosb mov ax, '= ' ;' =' stosw stosb ;' ' mov al, '-' ;'-', число отрицательное! stosb pop ax ;разность call PrDec ;сформируем числовую строку mov al, 0 ;закроем строку stosb push si ;сохраним адрес в строке lea si, sSub ;выведем call PrString pop si next: loop num_loop ;по всем finish: lea si, sAny ;выводим 'Press any key' call PrString
mov ah, 0 int 16h ;ждем нажатия mov ax, 4c0 0h ;завершаемся int 21h
PrString proc near ;выводим строку до 0 mov ah, 0eh ;ф-я вывода символа из al PSLoop: lodsb cmp al, 0 je PSRet int 10h jmp PSLoop PSRet: ret PrString endp
GetString proc ;ф-я для ввода числовой строки (аналог ф-и 0ah прерывания 21h) xor bx, bx GSLoop: mov ah, 0 int 16h cmp al, 0dh ;выход по 0dh je GSRet cmp al, 8 ;отработаем Backspace je GSBackSpace cmp bl, [di] ;проверим на максимум jae GSLoop cmp al, '0' ;проверим на цифры! jb GSLoop cmp al, '9' ja GSLoop mov [di+bx+2], al ;сохраним в String inc bx ;длина строки mov ah, 0eh ;выведем int 10h jmp GSLoop GSBackSpace: test bx, bx ;в начале строки низзя! jz GSLoop mov ax, 0e08h ;на позицию назад int 10h mov ax,0e20h ;пробел int 10h mov ax, 0e08h ;еще раз назад int 10h dec bx ;уменьшаем счетчик jmp GSLoop GS Ret: mov [di+1], bl ;count=bl mov byte ptr [di+bx+2], 0 ;закрываем нулем ret GetString endp
;выведем десятичное число PrDec proc push cx xor cx, cx ;количество цифр mov bx, 10 ;будем делить на 10 div_loop: xor dx, dx ;подготавливаемся к делению div bx ;dx:ax / bx push dx ;сохраним остаток - очередную младшую цифру inc cx ;считаем цифры test ax, ax ;есть еще? jnz div_loop out_loop: ;выводим в обратном порядке pop ax ;извлечем из стека or al, '0' ;превратим в символ stosb ;сохраним в буфере очередной символ-цифру loop out_loop ;по всем pop cx ret PrDec endp
end
----- Удачи! Ответ отправил: Лысков Игорь Витальевич, Старший модератор Ответ отправлен: 14.06.2010, 16:18 Номер ответа: 262105 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 262105 на номер 1151 (Россия) | Еще номера » | Отвечает Зенченко Константин Николаевич, Модератор : Здравствуйте, Даниил Цветков.
Смотрите приложение. Использованы только прерывания BIOS. Признаком окончания ввода последовательности, служат введенные два нуля. Удачи! Приложение: ----- Итерация от человека. Рекурсия — от Бога. — Л. Питер Дойч Ответ отправил: Зенченко Константин Николаевич, Модератор Ответ отправлен: 14.06.2010, 17:33 Номер ответа: 262107 Украина, Киев Тел.: +38-097-953-66-19 Адрес: Украина, Киев Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 262107 на номер 1151 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий