Разбить заданную строку на две части - Assembler
Формулировка задачи:
добрый день
нужна программа, содержащая в себе подпрограмму, которая разбивает заданную строку на две части: первое слов (до первого пробела) и остальная часть строки (пробелы в начале строки убираются)
после выполнения программы все слова выводятся в консоль по отдельности
надыбал код не помню на каком сайте. проверил - работает. стал вникать в принципы ее реализации.. ии... всё )) ничего не понял
может кто-то намекнуть на правильные ответы для возникших вопросов?)
какой механизм использован в 16-17 строках?
мы вносим в bMax максимальное значение строки, а после туда же пишем строку, которую нам необходимо в будущем анализировать?
если так, то как мы получаем доступ к этой строке в процедуре, если название bMax после нигде не используется.
я, конечно, читал о структуре буфера. первый байт - максимальная длина строки, второй - фактическая, а с третьего идет сами данные.. как-то это взаимосвязано?)
.186 ;чтобы можно было использовать push <число> assume cs:code, ds:data, es:data SSEG segment stack ;сегмент стека db 400h dup (?) SSEG ends code segment para public 'code' start: mov ax, data mov ds, ax mov es, ax ;пусть es=ds=data lea dx, sString mov ah, 9 int 21h ;ждем строку mov bMax, 80 ;задаем максимальное значение строки (в нулевом будет 80 - макс длина) lea dx, bMax ;в первом после ввода останется фактич длина, а со второй идут данные mov ah, 0ah int 21h ;вводим строку lea dx, sResult mov ah, 9 int 21h ;выводим заголовок о выводе слов mov wAddr, offset bString ;адрес строки next: push offset wAddr ;адрес адреса строки call FirstWord ;разбиваем на подстроки test ax, ax ;ax = адресу слова, =0 - одни пробелы jz finish ;в конце пробелы - на выход mov dx, ax mov ah, 9 int 21h ;выведем слово mov ah, 2 ;на новую строку mov dl, 0dh int 21h mov dl, 0ah int 21h cmp wAddr, 0 ;последнее слово? jne next ;продолжаем разбивать строку finish: lea dx, sPress mov ah, 9 int 21h ;press any key mov ah, 8 int 21h ;ждем any key mov ax, 4c00h int 21h ;bye ;Разбор строки на первое слово и все остальное ;Исходная строка портится! В конце слова ставится $ для вывода по 9 функции ;Параметр - адрес слова с адресом строки ;Возвращается в ax адрес первого слова, в слове с адресом строки ; возвращается адрес подстроки, начинающейся за первым словом или 0 для последнего слова ppStr equ [bp+4] ;адрес адреса строки FirstWord proc push bp mov bp, sp xor cx, cx ;адрес первого слова mov bx, ppStr ;адрес адреса строки mov si, [bx] ;адрес строки SearchBegin: ;цикл разбора строки lodsb ;очередной символ cmp al, 0dh ;конец строки je FW_last ;строка из одних пробелов cmp al, ' ' ;пробел? je SearchBegin ;первые пробелы обходим lea cx, [si-1] ;адрес начала слова SearchEnd: ;ищем конец слова lodsb ;очередной символ cmp al, 0dh ;конец строки je FW_last ;последнее слово cmp al, ' ' ;конец слова? jne SearchEnd ;ищем пробел после слова mov byte ptr [si-1], '$' ;поставим вместо пробела '$' для вывода jmp FW_ret ;на выход FW_last: ;последнее слово или одни пробелы mov byte ptr [si-1], '$' ;поставим вместо пробела '$' для вывода xor si, si ;больше слов нет FW_ret: mov [bx], si ;сохраним адрес второй подстроки или 0, если больше слов нет mov ax, cx ;возвращаем адрес первого слова для вывода pop bp ret 2 ;уберем из стека параметр FirstWord endp code ends data segment para public 'data' sString db 0ah,'Enter string: $' sResult db 0ah,0ah,'Words:',0dh,0ah,'$' sPress db 0dh,0ah,'Press any key$' ;буфер для ввода числовой строки (для функции 0ah) bMax db ? ;максимальный размер буфера bCount db ? ;реальный размер строки bString db 80 dup (?) ;сама строка wAddr dw ? ;адрес анализируемой строки data ends end start
Решение задачи: «Разбить заданную строку на две части»
textual
Листинг программы
org 100h jmp start mes0 db 13,10,'String: $' mes1 db 13,10,' Words: $' bMax db 80 ; макс.размер буфера bLen db 0 ; длина строки bStr db 80 dup(0) ; буфер источника buff db 32 dup('$') ; буфер приёмника start: mov dx,mes0 ; call message ; mov ah,0Ah ; заполяем источник строкой юзера mov dx,bMax ; int 21h ; mov si,bStr ; адрес начала строки для LODSB printWord: ; call findSpace ; заполняем приёмный буфер cmp byte[buff],'$' ; буфер пустой? je printWord ; mov dx,mes1 ; в приёмнике что-то есть. мессага! call message ; mov dx,buff ; выводим данные из буфера call message ; jmp printWord ; ищем сл.слово в источнике stop: ; mov al,7 ; бипер.. int 29h ; xor ax,ax ; int 16h ; int 20h ; выход! ;нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн message: ;=================================================== mov ah,9 ; int 21h ; ret ; findSpace: ;================================================= mov cx,32 ; очистим приёмный буфер mov al,'$' ; mov di,buff ; push di ; rep stosb ; ;-----------------------;-- pop di ; @1: lodsb ; читаем символ из SI cmp al,0Dh ; всю строку юзера проверили? je endStr ; cmp al,' ' ; пробел? je @2 ; stosb ; нет - сохраняем символ в приёмнике jmp @1 ; сл.символ.. @2: ; ret ; выход из процедуры! endStr: ; выход из внешнего цикла! pop ax ; снимаем CALL'овский адрес возврата jmp stop ;
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д