На этом шаге мы приведем программу, обрабатывающую строки.
Текст программы содержит комментарии, которые объясняют принцип ее работы.
TITLE Задача 52_1.
;Написать программу, которая удаляет в данном тексте все лишние пробелы
;(без учета концевых пробелов).
;Программа сделана как EXE-файл.
;-------------------------------
EXTRN Clear:FAR,Write_Str:FAR,Cursor:FAR
;----- Сегмент стека
StackSg SEGMENT PARA STACK 'Stack'
DW 256 DUP(?)
StackSg ENDS
;----- Сегмент данных
DataSg SEGMENT PARA PUBLIC
STR1 DB "Задайте исходную строку: $"
STR2 DB "Результирующая строка: $"
BUFFER LABEL BYTE ;Список параметров:
MAXLEN DB 250 ; максимальная длина;
ACTLEN DB ? ; реальная длина;
NAMEFLD DB 251 DUP ("$") ; введенные символы.
DataSg ENDS
;----- Сегмент кода
CodeSg SEGMENT PARA PUBLIC
ASSUME CS: CodeSg, DS:DataSg, SS: StackSg
Begin PROC FAR
;Пролог EXE-файла.
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DataSg
MOV DS,AX
MOV ES,AX ;Инициализация регистра ES.
;Конец пролога.
CALL Clear ;Очистка экрана.
MOV DX,0000h
CALL Cursor ;Установка курсора.
LEA DX,STR1
CALL Write_Str
MOV DX,0100h
CALL Cursor ;Установка курсора.
;--------------Ввод строки.
MOV AH,0AH ;Запрос функции ввода.
LEA DX,BUFFER ;Загрузить адрес списка параметров.
INT 21H ;Вызвать DOS-прерывание.
MOV AX,0
MOV AL,ACTLEN
MOV SI,AX
MOV BYTE PTR NAMEFLD[SI],'$' ;Поместим признак конца строки.
;--------------Проверим, нет ли пробелов сначала строки.
;--------------Если есть, то удалим их.
CALL Beg_Space
;Будем искать пару пробелов в строке.
;Когда найдем, то удалим второй из них
;путем сдвижки строки на один символ влево
;на место второго из найденных пробелов.
;Процесс будем повторять до тех пор,
;пока в строке есть пара пробелов.
PROD:
MOV CX,0
MOV AX,2020h
MOV CL,ACTLEN ;Длина строки
LEA DI,NAMEFLD;Адрес начала строки
REPNE SCASW ;Ищем пару пробелов.
JNZ EXT ;Нет двух рядом стоящих пробелов - выход.
MOV SI,DI
DEC SI ;Откуда копировать.
SUB DI,2 ;Куда.
REP MOVSB ;Перемещение строки.
JMP PROD ;Повторение операции
EXT: ;-------------Вывод результата.
MOV DX,0500h
CALL Cursor ;Установка курсора.
LEA DX,STR2
CALL Write_Str
MOV DX,0600h
CALL Cursor ;Установка курсора.
LEA DX,NAMEFLD
CALL Write_Str
MOV AH,1 ;Задержка.
INT 21H
RET
Begin ENDP
;---------------- Процедура удаления начальных пробелов.
Beg_Space PROC
PUSH CX
PUSH AX
PUSH BX
XOR CX,CX
XOR AX,AX
XOR BX,BX
CLD
MOV AL,' ' ;Искомый символ.
MOV CL,ACTLEN ;Длина строки.
MOV BL,CL
DEC BL
LEA DI,NAMEFLD;Адрес строки.
REPE SCASB ;Поиск символа, отличного от пробела.
CMP CL,BL ;Если нет пробелов вначале строки,
;то CX будет на единицу меньше.
;CX уменьшилось на 1?
JE EXIT ;Да - вначале строки пробелы отсутствуют.
;--------------Удалим лишние пробелы.
DEC DI
MOV SI,DI ;Откуда.
LEA DI,NAMEFLD ;Куда.
MOV CL,ACTLEN ;Количество повторений.
REP MOVSB ;Перемещение строки.
EXIT:
POP BX
POP AX
POP CX
RET
Beg_Space ENDP
CodeSg ENDS
END Begin
Со следующего шага мы начнем рассматривать работу с файлами.