Вопрос № 183162: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: требуется составить подпрограмму решения задачи, использующую инструкции обработки цепочек. Составить программу, осуществляющую ввод необходимых данных, вызов подпрограммы и вы...
Вопрос № 183162:
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: требуется составить подпрограмму решения задачи, использующую инструкции обработки цепочек. Составить программу, осуществляющую ввод необходимых данных, вызов подпрограммы и вывод результата. Задача- сформировать строку, содержащую данный символ указанное число раз. Ассемблер-TASM. EXE. Очень надеюсь, что Вы мне поможете.
Отправлен: 13.05.2011, 23:11
Вопрос задал: Сanijke
Всего ответов: 1 Страница вопроса »
Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Сanijke! Правильно делаете, что надеетесь У нас Вы всегда найдете решение Ваших проблем. Небольшой вопрос: где разместить буфер под строку? Можно делать по-разному. Например, в сегменте данных, за программой, можно сделать, чтобы память выделялась при помощи функции 48h. Мне вот захотелось выделить динамический буфер под строку в стеке. Запросив сначала длину строки,
выделяем память в стеке, при этом учитываем, что надо еще разместить завершающий нуль и то, чтобы значение вершины стека (SP) оставалось кратным 2.
Код :
;требуется составить подпрограмму решения задачи,
;использующую инструкции обработки цепочек.
;Составить программу, осуществляющую ввод необходимых данных,
;вызов подпрограммы и вывод результата.
;Задача - сформировать строку, содержащую данный символ указанное число раз.
.model small,C
.data
;строки сообщений
sGetSym db 0dh,0ah,'Enter symbol:$'
sGetCnt db 0dh,0ah,'Enter count: $'
sOutStr db 0dh,0ah,'String = $'
sAny db 0dh,0ah,'Press any key$'
.code
start:
mov ax, @data ;настраиваем все сегментные
mov ds, ax ;регистры (включая стек)
mov es, ax ;на сегмент данных
mov ss, ax
call GetNum ;вводим количество в AX
mov cx, ax ;сохраним в CX
;выделим память в стеке
inc ax ;учтем конечный 0 и округление
inc ax ;до слова
and ax, 0fffeh ;округлим до слова
mov bp, sp ;сохраним положение вершины стека
sub sp, ax ;выделяем буфер в стеке
mov bx, sp ;адрес буфера в bx, длина строки в cx
call GetSym ;введем символ
call FormStr ;сформируем в буфере [bx] строку из cx символов
call PrintStr ;выведем строку
mov sp, bp ;"выкинем" из стека буфер
lea dx, sAny ;выведем 'Press any key'
mov ah, 9
int 21h
mov ah, 0 ; ждем нажатие на клавишу
int 16h
mov ax,4c00h ; конец работы
int 21h
GetSym proc ;ввод символа
lea dx, sGetSym
mov ah, 9
int 21h ; приглашение ввести символ
GetSymLoop:
mov ah, 0 ;ждем нажатие на клавиатуру
int 16h
cmp al, 0 ;управляющие клавиши игнорируем
je GetSymLoop
mov dl, al ;выведем на экран
mov ah, 2
int 21h
ret ;результат в al
GetSym endp
GetNum proc ;ввод числа < 32767 (чтобы поместилось в стеке)
lea dx, sGetCnt
mov ah, 9
int 21h ; приглашение ввести число
xor di, di ; здесь будем накапливать число
xor bx, bx ; очередной дес разряд (для сложения со словом)
GetNumLoop:
mov ah, 0 ;ждем нажатие на клавиатуру
int 16h
cmp al, 0dh ;по Enter-у завершаемся
je GetNumRet
cmp al, '0' ;нецифры игнорируем
jb GetNumLoop
cmp al, '9'
ja GetNumLoop
mov ah, 2 ;выведем на экран
mov dl, al
int 21h
and al, 0fh ; цифра -> число (30h-39h -> 0-9)
mov bl, al ; сохраним (bh=0)
mov ax, 10 ; умножим на 10
mul di ; предыдущее значение
test dx, dx ; больше cлова - ошибка!
jnz GetNumLoop
add ax, bx ; добавим сохраненный разряд
jc GetNumLoop ; больше слова - ошибка!
js GetNumLoop ; больше 32767 - ошибка!
mov di, ax ; сохраним
jmp GetNumLoop ; на ввод следующей цифры
GetNumRet:
mov ax, di ; результат в ax
ret
GetNum endp
FormStr proc ;формирование строки
mov di, bx ;адрес строки - es:di
rep stosb ;в cx количество, в al символ
mov al, 0 ;закроем строку нулем
stosb
ret
FormStr endp
PrintStr proc ;вывод строки
lea dx, sOutStr
mov ah, 9
int 21h ;поясняющая строка
mov si, bx ;адрес строки
mov ah, 2 ;функция вывода символа
PrintLoop:
lodsb ;читаем
cmp al, 0 ;пока не 0
je PrintStrRet
mov dl, al ;символ для вывода
int 21h
jmp PrintLoop ;по всем
PrintStrRet:
ret
PrintStr endp
end start
Примерный вывод программы:
Код :
Enter count: 12
Enter symbol:z
String = zzzzzzzzzzzz
Press any key
----- Люби своего ближнего, как самого себя
Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 14.05.2011, 01:55
Номер ответа: 267142 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 267142
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.