(MASM) Удаление второй подстроки из первой и сохранение результата третью - Assembler
Формулировка задачи:
Здравствуйте! Три дня ломал голову над задачей и все-таки решил прибегнуть к вашей помощи.
Даны три строки, S1, S2, S3. Удалить из S1 первое появление S2, остаточную строку записать в S3. Вывести все три строки.
Вот мои безуспешные попытки
Листинг программы
- include Irvine32.inc
- Show macro string
- lea edx, string
- call WriteString
- call Crlf
- endm
- .data
- S1 db '3331234222222453322222222345',0
- S2 db '345',0
- S3 db sizeof S1 dup(0)
- len_S2 dd ?
- len_S1 dd ?
- s3_edi dd ?
- .code
- main proc
- Show S1
- ;lab S1, S2, S3
- cld
- mov edi, offset S2
- Invoke Str_length, edi
- mov len_S2, eax
- mov edi, offset S1
- Invoke Str_length, edi
- mov len_S1, eax
- lea edi, S3
- mov s3_edi, edi
- lea esi, S1
- lea edi, S2
- srch:
- lea edi, S2
- mov ecx, len_S2
- repe cmpsb
- jne mismatch
- jmp ext
- mismatch:
- pusha
- dec esi
- dec edi
- lodsb
- mov edi, s3_edi
- stosb
- popa
- inc s3_edi
- jmp srch
- ext:
- Show S2
- Show S3
- exit
- main endp
- end main
Решение задачи: «(MASM) Удаление второй подстроки из первой и сохранение результата третью»
textual
Листинг программы
- org 100h
- jmp start
- Str1 db 'ANBC-HD*G_HJV0125800 BKMC4 NX3451185ABCGEF00245',0
- len1 = ($ - Str1)-1 ; длина строки (без нуль-терминала)
- Str2 db '345',0
- len2 = ($ - Str2)-1
- Str3 db 80 dup(0)
- crlf db 13,10,'$'
- start:
- mov bx,len1 ; BX = длина строки
- xor ax,ax ; плавающая позиция
- xor dx,dx ; это будет найденая позиция в строке
- @@: ;
- mov si,Str1 ; указатель на строку
- mov di,Str2 ; ..и на под/строку
- mov cx,len2 ; длина под/строки
- add si,ax ; добавляем плавающую позицию
- mov dx,si ; запоминаем эту позицию
- repe cmpsb ; сравниваем строки
- jz @f ; переход, если есть вхождение
- inc ax ; иначе: позиция поплыла вперёд
- dec bx ; ..а счётчик назад
- jnz @b ; если не конец строки, то циклимся..
- ; ошибка поиска! ====================================================//
- mov al,7 ; бипер,
- int 29h ;
- jmp exit ; ..и на выход!
- ; Есть вхождение!
- ; На этом этапе SI установлен на первом/найденном символе, плюс длина под/строки.
- ; DX указывает на первый/найденный символ.
- @@: ;
- mov di,dx ; вставляем по-адресу DX,
- xor al,al ; ..нуль-терминал (отрезали хвост).
- stosb ;
- lea cx,[Str1+len1] ; вычисляем длину хвоста
- sub cx,dx ;
- sub cx,len2 ; ..без под/строки
- mov di,Str3 ; DI приёмник, SI источник
- rep movsb ; копируем СХ-байт из SI в DI
- mov si,Str1 ; выводим на экран получившиеся строки
- call WriteString ; эта функция выводит строку на консоль (по-байтно),
- mov si,Str2 ; ..пока не встретится нуль-терминал.
- call WriteString ;
- mov si,Str3 ;
- call WriteString ;
- exit: ;
- xor ax,ax ;
- int 16h ;
- int 20h ; на выход!
- ;ннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн
- WriteString: ;
- mov dx,crlf ; курсор на новую строку
- mov ah,9 ;
- int 21h ;
- @@: ;
- lodsb ; читаем байт из SI
- or al,al ; нуль-терминал?
- jz @f ;
- int 29h ; нет - печатаем символ.
- jmp @b ;
- @@: ;
- ret ;
Объяснение кода листинга программы
Код на языке Assembler выполняет удаление второй подстроки из первой и сохранение результата третьей. Список действий:
- Переменная
len1
содержит длину строкиStr1
(включая нуль-терминал), вычисленную как разность междуStr1
и нуль-терминалом. - Переменная
len2
содержит длину подстрокиStr2
, вычисленную как разность междуStr2
и нуль-терминалом. - Переменная
Str3
содержит результат, который будет отправлен на консоль. - В цикле сравниваются символы строки
Str1
и подстрокиStr2
. Если символы совпадают, то увеличивается счётчик совпадений в регистреbx
. - Если счётчик совпадений равен нулю, то регистры
si
иdi
инкрементируются на длину подстроки, и цикл продолжается. - Если счётчик совпадений не равен нулю, то увеличивается регистр
ax
, который является плавающей позицией в строке. - Делается переход на начало цикла, чтобы продолжить поиск совпадений.
- Если счётчик совпадений равен нулю, то делается переход на выход из программы.
- Если счётчик совпадений не равен нулю, то происходит копирование символов из строки
Str1
в строкуStr3
. - Выводится на консоль строка
Str3
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д