Вопрос № 179054: Доброго времени суток, уважаемые эксперты! Помогите, пожалуйста решить ещё одну задачу для ТАСМ по теме "Прерывания": С клавиатуры вводится последовательность цифр. Нужно выдать на экран разность каждой предыдущей и последующей цифры,...
Вопрос № 179054:
Доброго времени суток, уважаемые эксперты! Помогите, пожалуйста решить ещё одну задачу для ТАСМ по теме "Прерывания": С клавиатуры вводится последовательность цифр. Нужно выдать на экран разность каждой предыдущей и последующей цифры, если эта разность отрицательное число.
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
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 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.