Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.04.2023, 13:44   #1
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
Радость с решение ошибок в коде нужно Удалить слово в строке, стоящее перед заданным словом.

помогите с решение ошибок в коде нужно Удалить слово в строке, стоящее перед заданным словом.
Код:
.model small
.stack 100h
.data
    message1 db 'Found$'
    message2 db 'String: $'
    message3 db 'Word: $'
    buffer   db 256, 0
.code
start:
    ; установка сегмента данных
    mov ax, @data
    mov ds, ax
    ; вывод сообщения "String:"
    mov ah, 09h
    mov dx, offset message2
    int 21h
    ; чтение строки
    mov ah, 0Ah
    mov dx, offset buffer
    int 21h
    ; вывод сообщения "Word:"
    mov ah, 09h
    mov dx, offset message3
    int 21h
    ; чтение слова
    mov ah, 0Ah
    mov dx, offset buffer+256 ; использование второй половины буфера
    int 21h
    ; поиск позиции заданного слова в строке
    lea si, buffer+2 ; начало строки
    mov di, offset buffer+256+2 ; начало заданного слова
    mov cx, 0 ; счетчик слов
find_word:
    ; ищем конец слова
    cmp byte ptr [si], ' '
    je word_end
    cmp byte ptr [si], 0
    je end_search
    inc si
    jmp find_word
word_end:
    cmp byte ptr [di], 0
    je end_search
    inc cx
    inc di
    jmp find_word
end_search:
    ; если слово не найдено, завершаем программу
    cmp cx, 0
    je exit_program
    ; находим начало предыдущего слова
    lea si, buffer+2 ; начало строки
    mov bx, 0 ; счетчик слов
previous_word:
    cmp byte ptr [si], ' '
    je space_found
    cmp byte ptr [si], 0
    je end_previous_word
not_space_found:
    inc si
    jmp previous_word
space_found:
    inc bx
    cmp bx, cx
    jne continue_previous_word
    dec si ; возврат на последнюю букву предыдущего слова
    ; сдвигаем оставшуюся часть строки на место удаленного слова
    lea di, buffer+2 ; начало строки
    add di, si
    add si, 1 ; переход к началу слова для удаления
    shift:
    mov al, [si]
    mov [di], al
    inc si
    inc di
    cmp byte ptr [si], 0
    jne shift
    ; выводим измененную строку
    mov ah, 09h
    mov dx, offset message1
    int 21h
    mov dx, offset buffer+2
    int 21h
exit_program:
    ; возвращаем управление операционной системе
    mov ah, 4Ch
    int 21h
end start
но в коде 3 ошибки не могу понять как решить очень нужно
ChestIotVaga вне форума Ответить с цитированием
Старый 09.04.2023, 15:29   #2
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

1) Я вам уже несколько раз говорил про дополнительный сегмент данных, но вы попрежнему продолжаете игнорировать его настройку!
Код:
    mov ax, @data
    mov ds, ax
    mov es, ax
2)Для функции 10 необходимо правильно подготовить буфер
Код:
    buffer   db 256, 0
Код:
    mov ah, 0Ah
    mov dx, offset buffer
    int 21h
Сначала должен идти байт указывающий количество байт в буфере, потом байт, куда будет помещена длина данных записанных в буфер и только после этого байта будут идти байты буфера (количеством равным указанному в первом байте)
Код:
buffer   db 255,0,255 dup(0)
3) О какой второй половине буфера тут говорится, если вы не выделили буфер даже для первой части.
Код:
    mov ah, 0Ah
    mov dx, offset buffer+256 ; использование второй половины буфера
    int 21h
В вашей переменной buffer объявлено всего 2 значения. А одно из них вообще превышает максимальное значение, помещающееся в DB. Лучше объявить вторую переменную buffer2 т.к. она должна быть также подготовлена для использования в функции 10.
Код:
buffer2  db 255,0,255 dup(0)
4) Для поиска стоит полагаться не на наличие 0 в конце данных, а на длину, которую вернула функция 10
Код:
    movzx ax, buffer[1]
    movzx dx, buffer2[1]
    add ax, si
    add dx, di
    mov word ptr buffer[0], ax
    mov word ptr buffer2[0], dx
find_word:
...
    cmp byte ptr [si], 0
    cmp si, word ptr buffer[0]
    je end_search
...
    cmp byte ptr [di], 0
    cmp di, word ptr buffer2[0]
    je end_search
...
    cmp byte ptr [si], 0
    cmp si, word ptr buffer[0]
    je end_previous_word
5) Кажется тут вы забыли сравнение со словом в первом буфере
Код:
word_end:
    cmp byte ptr [di], 0
    cmp di, word ptr buffer2[0]
    je end_search
    inc cx
    inc di
    jmp find_word
Иначе вы в цикле продолжаете искать после каждого слова в основном буфере конец слова во втором буфере. Разумеется на второй итерации (на втором слове) вы уже ищите завершение после конца слова во втором буфере

6) А тут вы сравниваете количество слов (bx) с длиной слова в символах (cx)
Код:
    cmp bx, cx
    jne continue_previous_word
7) Здесь вы забыли про смещение buffer в сегменте данных
Код:
    lea di, buffer+2 ; начало строки
    add di, si
    mov di, 1
    add si, 1 ; переход к началу слова для удаления
    shift:
    mov al, [si]
    mov al, buffer[di]
    mov [di], al
    mov buffer[si], al

Последний раз редактировалось macomics; 09.04.2023 в 15:44.
macomics вне форума Ответить с цитированием
Старый 09.04.2023, 17:25   #3
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
По умолчанию

не могли бы дать полностью код боюсь напортачить а сдать преподу надо через 2 часа
ChestIotVaga вне форума Ответить с цитированием
Старый 09.04.2023, 17:28   #4
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
По умолчанию

вот так верно @macomics
Код:
.model small
.stack 100h
.data
    message1 db 'Found$'
    message2 db 'String: $'
    message3 db 'Word: $'
    buffer   db 255, 0, 255 dup(0)
    buffer2  db 255, 0, 255 dup(0)
.code
start:
    ; установка сегмента данных
    mov ax, @data
    mov ds, ax
    mov es, ax
    ; вывод сообщения "String:"
    mov ah, 09h
    mov dx, offset message2
    int 21h
    ; чтение строки
    mov ah, 0Ah
    mov dx, offset buffer
    int 21h
    ; вывод сообщения "Word:"
    mov ah, 09h
    mov dx, offset message3
    int 21h
    ; чтение слова
    mov ah, 0Ah
    mov dx, offset buffer2
    int 21h
    ; поиск позиции заданного слова в строке
    lea si, buffer+2 ; начало строки
    mov di, offset buffer2+2 ; начало заданного слова
    mov cx, 0 ; счетчик слов
find_word:
    ; ищем конец слова
    cmp byte ptr [si], ' '
    je word_end
    cmp byte ptr [si], 0
    je end_search
    inc si
    jmp find_word
word_end:
    cmp byte ptr [di], 0
    je end_search
    inc cx
    inc di
    jmp find_word
end_search:
    ; если слово не найдено, завершаем программу
    cmp cx, 0
    je exit_program
    ; находим начало предыдущего слова
    lea si, buffer+2 ; начало строки
    mov bx, 0 ; счетчик слов
previous_word:
    cmp byte ptr [si], ' '
    je space_found
    cmp byte ptr [si], 0
    je end_previous_word
not_space_found:
    inc si
    jmp previous_word
space_found:
    inc bx
    cmp bx, cx
    jne continue_previous_word
    dec si ; возврат на последнюю букву предыдущего слова
    ; сдвигаем оставшуюся часть строки на место удаленного слова
    lea di, buffer+2 ; начало строки
    add di, si
    add si, 1 ; переход к началу слова для удаления
    shift:
    mov al, [si]
    mov [di], al
    inc si
    inc di
    cmp byte ptr [si], 0
    jne shift
    ; выводим измененную строку
    mov ah, 09h
    mov dx, offset message1
    int 21h
    mov dx, offset buffer+2
    int 21h
exit_program:
    ; возвращаем управление операционной системе
    mov ah, 4Ch
    int 21h
end start
ChestIotVaga вне форума Ответить с цитированием
Старый 09.04.2023, 17:36   #5
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
По умолчанию

@macomics вы тут?
ChestIotVaga вне форума Ответить с цитированием
Старый 09.04.2023, 19:44   #6
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

А зачем на форуме кружочки под сообщениями. Они показывают кто в сети.
Нет не правильно.
Код:
.model small
.stack 100h
.data
    message1 db 'Found$'
    message2 db 'String: $'
    message3 db 'Word: $'
    buffer   db 255, 0, 255 dup(0)
    buffer2  db 255, 0, 255 dup(0)
.code
start:
    ; установка сегмента данных
	mov	ax, @data
	mov	ds, ax
	mov	es, ax
    ; вывод сообщения "String:"
	mov	ah, 09h
	mov	dx, offset message2
	int	21h
    ; чтение строки
	mov	ah, 0Ah
	mov	dx, offset buffer
	int	21h
    ; вывод сообщения "Word:"
	mov	ah, 09h
	mov	dx, offset message3
	int	21h
    ; чтение слова
	mov	ah, 0Ah
	mov	dx, offset buffer2
	int	21h
    ; поиск позиции заданного слова в строке
	cld
	lea	di, buffer[2] ; начало строки
	xor	cx, cx
	mov	al, buffer2[2] ; искомый символ
	mov	cl, buffer[1] ; длина строки
	mov	dx, [di + 1]  ; фиксация позиции первого слова в строке

not_found:
	repne	scasb 		; поиск символа в строке
	jnz	not_found
	cmp	dx, di
	jz	not_found 	; поидее тут искомое слово может быть в начале строки, но тогда нету слова для стирания, поэтому переходим на not_found
	cmp	byte ptr [di - 2], ' ' ; проверка, что символ находится в начале слова
	jnz	not_found	; нет, слово не начинается на этот символ, совпавший с началом искомого слова
	lea	si, buffer[3]	; загружаем адрес второго символа искомого слова т.к. первый символ уже совпал
	push	cx		; сохраняем количество символов в строке поиска
	push	di		; сохраняем позицию в строке для поиска
	mov	cl, buffer2[1]	; загружаем длину искомого слова
	dec	cx		; уменьшаем длину на 1 т.к. первый символ уже совпал
	repe	cmpsb		; сравниваем остальную часть искомого слова с найденным
	mov	bx, di		; сохраняем адрес конца слова для дальнейших проверок
	pop	di		; восстанавливаем позицию в строке поиска
	pop	cx		; восстанавливаем количество символов до конца строки
	jnz	not_found	; слово не совпало, продолжаем поиск
	cmp	byte ptr es:[bx], ' ' ; проверка, что слово совпало целиком
	jnz	not_found	; не совпало
	lea	si, [di - 1]	; вычислили адрес начала искомого слова в строке
	mov	bx, cx		; сохранили количество символов до конца строки поиска
	std			; а теперь строковые команды будут работать в обратном порядке
	dec	dx		; теперь dx содержит адрес начала строки, а не второго символа
	mov	cx, di		; вычисляем длину строки от текущей позиции
	sub	cx, dx		; теперь cx содержит количество символов проверенное от начала строки
	mov	al, ' '		; теперь будет искать начало предыдущего слова
	dec	di		; корректировка адреса для работы строковой команды в обратном порядке
	repne	scasb		; просматриваем строку от текущей позиции к началу и ищем пробел
	jz	word_found	; пробел найден - начало предыдущего слова
	inc	bx		; пробел не найден - предыдущее слово первое в строке
	inc	di		; корректировка адресов для копирования
	dec	si		; корректировка количества символов для копирования
word_found:
	cld			; а теперь строковые команды будут работать как надо
	mov	cx, bx		; загружаем количество символов до конца строки
	rep	movsb		; копируем конец строки стирая предыдущее слово
	mov	al, '$'		; добавляем в строку символ $, чтобы обрезать её
	stosb			; при выводе
	mov	ah, 09h
	mov	dx, offset message1
	int	21h
	mov	dx, offset buffer+2
	int	21h
exit_program:
    ; возвращаем управление операционной системе
	mov	ah, 4Ch
	int	21h
end start
не проверял, набирал в браузере
macomics вне форума Ответить с цитированием
Старый 09.04.2023, 20:12   #7
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
По умолчанию

скомпилировалось без ошибок но вот после вода строки потом выдает поверх ворд и дальше нечего не могу писать
ChestIotVaga вне форума Ответить с цитированием
Старый 09.04.2023, 20:15   #8
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
По умолчанию

то есть она сразу просит string не предлагая found и тд
ChestIotVaga вне форума Ответить с цитированием
Старый 09.04.2023, 21:47   #9
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Поправил кое что. Заодно добавил перевод строки в сообщениях, чтобы они отображались правильно, а не друг на дуге. Но все равно не проверял. Вам проще взять отладчик и пройти программу по шагам, наблюдая за данными, которые она обрабатывает. В комплекте TASM есть прекрасный TUI отладчик. Вы сможете разобраться в проблемах программы быстрее самостоятельно.
Код:
.model small
.stack 100h
.data
    message1 db 13,10,'Found:  $'
    message2 db 'String: $'
    message3 db 13,10,'Word: $'
    buffer   db 255, 0, 255 dup(0)
    buffer2  db 255, 0, 255 dup(0)
.code
start:
    ; установка сегмента данных
	mov	ax, cs; @data
	mov	ds, ax
	mov	es, ax
    ; вывод сообщения "String:"
	mov	ah, 09h
	mov	dx, offset message2
	int	21h
    ; чтение строки
	mov	ah, 0Ah
	mov	dx, offset buffer
	int	21h
    ; вывод сообщения "Word:"
	mov	ah, 09h
	mov	dx, offset message3
	int	21h
    ; чтение слова
	mov	ah, 0Ah
	mov	dx, offset buffer2
	int	21h
    ; поиск позиции заданного слова в строке
	cld
	lea	di, [buffer+2] ; начало строки
	xor	cx, cx
	mov	al, [buffer2+2] ; искомый символ
	mov	cl, [buffer+1] ; длина строки
	lea	dx, [di + 1]  ; фиксация позиции первого слова в строке

not_found:
	repne	scasb 		; поиск символа в строке
	jnz	exit_loop
	cmp	dx, di
	jz	not_found 	; поидее тут искомое слово может быть в начале строки, но тогда нету слова для стирания, поэтому переходим на not_found
	cmp	byte ptr [di - 2], ' ' ; проверка, что символ находится в начале слова
	jnz	not_found	; нет, слово не начинается на этот символ, совпавший с началом искомого слова
	lea	si, [buffer2+3]	; загружаем адрес второго символа искомого слова т.к. первый символ уже совпал
	push	cx		; сохраняем количество символов в строке поиска
	push	di		; сохраняем позицию в строке для поиска
	mov	cl, [buffer2+1]	; загружаем длину искомого слова
	dec	cx		; уменьшаем длину на 1 т.к. первый символ уже совпал
	repe	cmpsb		; сравниваем остальную часть искомого слова с найденным
	mov	bx, di		; сохраняем адрес конца слова для дальнейших проверок
	pop	di		; восстанавливаем позицию в строке поиска
	pop	cx		; восстанавливаем количество символов до конца строки
	jnz	not_found	; слово не совпало, продолжаем поиск
	cmp	byte ptr [es:bx], ' ' ; проверка, что слово совпало целиком
	jnz	not_found	; не совпало
	mov	bx, cx		; сохранили количество символов до конца строки поиска
	std			; а теперь строковые команды будут работать в обратном порядке
	dec	dx		; теперь dx содержит адрес начала строки, а не второго символа
	lea	cx, [di - 1]	; вычисляем длину строки от текущей позиции
	sub	cx, dx		; теперь cx содержит количество символов проверенное от начала строки
	mov	al, ' '		; теперь будет искать начало предыдущего слова
	sub	di, 2		; корректировка адреса для работы строковой команды в обратном порядке
	repe	scasb		; пропускаем все пробелы перед первым словом
	lea	si, [di + 1]	; вычислили адрес начала искомого слова в строке
	repne	scasb		; просматриваем строку от текущей позиции к началу и ищем пробел
	jz	word_found	; пробел найден - начало предыдущего слова
	inc	bx		; пробел не найден - предыдущее слово первое в строке
	inc	di		; корректировка адресов для копирования
	dec	si		; корректировка количества символов для копирования
word_found:
	cld			; а теперь строковые команды будут работать как надо
	mov	cx, bx		; загружаем количество символов до конца строки
	rep	movsb		; копируем конец строки стирая предыдущее слово

exit_loop:
	mov	al, '$'		; добавляем в строку символ $, чтобы обрезать её
	stosb			; при выводе
	mov	ah, 09h
	mov	dx, offset message1
	int	21h
	mov	dx, offset buffer+2
	int	21h
exit_program:
    ; возвращаем управление операционной системе
	mov	ah, 4Ch
	int	21h
end start
macomics вне форума Ответить с цитированием
Старый 09.04.2023, 21:55   #10
ChestIotVaga
Пользователь
 
Регистрация: 21.11.2022
Сообщений: 84
По умолчанию

а как пользоваться этим отладчиком
ChestIotVaga вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вставить заданное слово в строку перед заданным словом ChestIotVaga Помощь студентам 4 03.04.2023 02:12
Вставить в строке перед заданным словом другое заданное слово Mayrlly Помощь студентам 1 28.04.2020 13:54
Ввести строку и слово. Вставить введенное слово перед самым длинным словом в строке.(программа на си) Кристина1998 Общие вопросы C/C++ 1 20.11.2016 11:15
Вставить заданное слово в строку перед заданным словом Blind Guard Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 5 07.04.2014 19:56
Вставить в строке перед заданным словом другое заданное слово. Axrik Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 23.04.2013 02:42