Сжатие строки (удаление пробелов и табуляций), найти ошибку - Assembler
Формулировка задачи:
Ввести с клавиатуры строку. Сжать строку, т.е. удалить про¬белы и табуляции. Вывести результаты на экран.
Не могу найти ошибку, убираются только первые 2 пробела, остальные игнорируются, и если строка начинается с пробела, то все пробелы игнорируются
.model small
stack 100h
dataseg
InviteStr db 0Dh, 0Ah, 'Vvedite stroku', 0Dh, 0Ah, '$'
StringINP db 16, ?, 16 dup(?)
StringOUT db 16, ?, 16 dup(?)
codeseg
start:
startupcode
xor SI,SI
xor DI, DI
lea DX, InviteStr ;приглашение ввести первую строку
mov AH, 09h
int 21h
lea DX, StringINP ;ввод строки
mov AH, 0Ah
int 21h
lea SI, StringINP+2 ;взятие адреса входящей строки
lea DI, StringOUT+2 ;взятие адреса исходящей строки
mov CL, StringINP+1
CLD
Check:
lodsb
cmp AL, 20h
je stop
mov DL, AL
mov AH, 02h
int 21h
stop: loop Check
quit:
exitcode 0
end startРешение задачи: «Сжатие строки (удаление пробелов и табуляций), найти ошибку»
textual
Листинг программы
;masm/DOS dos_inp macro lbl, sz _ib_ struc max db sz len db ? bf db sz dup(?) _ib_ ends lbl _ib_ <> endm .model small .386 .stack .data InviteStr db 0Dh, 0Ah, 'Vvedite stroku' crlf db 0Dh, 0Ah, '$' dos_inp StringINP, 16 .code start: mov ax, @data mov ds, ax mov es, ax lea DX, InviteStr ;приглашение ввести первую строку mov AH, 09h int 21h lea DX, StringINP ;ввод строки mov AH, 0Ah int 21h lea SI, StringINP.bf ;взятие адреса входящей строки movzx cx, StringINP.len lea dx, crlf mov ah, 9 int 21h @l: lodsb cmp AL, 20h jz @F cmp al, 09h jz @F int 29h @@: loop @l xor ax, ax int 16h mov ax, 4C00h int 21h end start
Объяснение кода листинга программы
- В начале кода определен макроопределение
dos_inp, которое используется для ввода строки с помощью функции BIOSint 21h. - Строка, которую необходимо ввести, представлена в сегменте данных (
data segment) и содержит приглашение для ввода строки. - После ввода строки, её адрес сохраняется в переменной
StringINP, а её длина сохраняется в переменнойStringINP.len. - Затем, в цикле, происходит проход по каждому символу входной строки. Если символ является пробелом или табуляцией, он пропускается, а если это не пробел или табуляция, он добавляется в выходную строку.
- При достижении символа новой строки или конца строки, цикл завершается.
- После завершения цикла, в цикле
whileдобавляется символ новой строки, и цикл завершается. - После этого, код завершается с помощью функции
int 21hс кодом выхода 4C00h. Список ошибок: - Не указан сегмент для переменных
StringINP,bfиlen. - Переменная
bfне используется в коде. - Переменная
lenне используется в коде, кроме как для вычисления длины строки. - При вычислении длины строки, возможно, будет деление на ноль, если строка пуста.
- В цикле, где происходит обработка каждого символа входной строки, не обрабатывается случай, когда символ равен 0Dh (символ новой строки).
- После обработки каждого символа входной строки, не выполняется переход к следующему символу.
- При добавлении символа в выходную строку, не выполняется проверка на переполнение буфера.