Создать подпрограмму, определяющую, содержится ли одна заданная строка в другой заданной строке - Assembler

Узнай цену своей работы

Формулировка задачи:

Разработать подпрограмму, которая определяет, содержится ли одна заданная строка в другой заданной строке, и если да, то, начиная с какой позиции. Разработать программу, которая вводит с клавиатуры две строки и сообщает, содержится ли одна из них в другой и сколько раз. не получается с самой подпрограммой!
locals __       ; определение префикса локальных переменных
.model SMALL    ; определение модели памяти
stack 200h      ; задаем размер стека - 512 байт
 
dataseg         ; определяем сегмент данных
COUNT_STR dw 0  ; число введенных строк
 
INFO_MESSAGE    db 0AH, 0DH
                db "Enter two lines"
                db 0AH, 0DH, '$'
 
INVITE_1        db 0Ah, 0Dh
                db "Enter the first line: $"
INVITE_2        db 0Ah, 0Dh
                db "Enter the second line: $"
 
INVITE_RESULT_1 db 0Ah, 0Dh
                db "YES! "
                db 0Ah, 0Dh, '$'
                
INVITE_RESULT_2 db 0Ah, 0Dh
                db "NO! "
                db 0Ah, 0Dh, '$'

PRESS           db 0Ah, 0Dh
                db "Exit - any $"
 
STR_1           db 80, ?, 82 dup ( ? )
STR_2           db 80, ?, 82 dup ( ? )
BUFFER          db 80, ?, 82 dup ( ? )
 
REPETITION      dw 0h                   ; количество одной строки в другой

codeseg                     ; определение сегмента кода
startupcode                 ; установление регистров DS и SS
 
lea DX, INFO_MESSAGE        ; в DX занести адрес строки
mov AH, 09h                 ; в АН занести номер функции
int 21h                     ; вызов прерывания
 
;ввод строк с клавиатуры 
 
InputStr:
    lea DX, INVITE_1        ; в DX занести адрес строки
    mov AH, 09h             ; в АН занести номер функции
    int 21h                 ; вызов прерывания
    lea DX, STR_1           ; в DX занести буфер для ввода
    mov AH, 0Ah             ; в АН занести номер функции
    int 21h                 ; вызов прерывания
    lea DX, INVITE_2        ; в DX занести адрес строки
    mov AH, 09h             ; в АН занести номер функции
    int 21h                 ; вызов прерывания
    lea DX, STR_2           ; в DX занести буфер для ввода
    mov AH, 0Ah             ; в АН занести номер функции
    int 21h                 ; вызов прерывания

FIND:
    ;;;; ПОИСК ;;;;
    lea DI,STR_1 
    lea SI,STR_2
    mov DX,REPETITION
 
    push DI            
    push SI
    push DX
    
    call StrFind    ; вызываем подпрограмму
    cmp DX, word ptr 0
    je NO
YES:
    lea DX, INVITE_RESULT_1 ; в DX занести адрес строки
    mov AH, 09h ; в АН занести номер функции 
    int 21h ; вызов прерывания
    jmp metka1
NO:
    lea DX, INVITE_RESULT_2 ; в DX занести адрес строки
    mov AH, 09h ; в АН занести номер функции 
    int 21h ; вызов прерывания              
    
metka1:
; пауза перед выходом из программы 
    lea DX, PRESS ; в DX занести адрес строки
    mov AH, 09h ; в АН занести номер функции 
    int 21h ; вызов прерывания
    mov AH, 08h ; в АН занести номер функции
    int 21h ; вызов прерывания
 
QUIT:
exitcode 0                  ; вернуть в ОС код возврата - 0

; подпрограмма поиска одной строки в другой
            ; аргументы 
            ; __num1 - индекс первой строки;
            ; __num2 - индекс второй строки;
            ; выходные значения 
            ; результат в REPETITION
 
StrFind proc near
 arg __num1:word, __num2:word,__num3:word = __ArgSize
 local  __FLAG: byte, __COUNT: word = __LocSize
 
push BP                     ; сохранить значение базового указателя
mov BP, SP                  ; базовому указателю присваиваем указатель стека
push SI DI                  ; сохраняем значение регистров SI и DI
push CX
 
mov SI, 4
mov     DI, 4
 
mov __FLAG, 0
mov __COUNT, 0
xor DX, DX
mov CX, __num1 + 1
mov DX, __num3
 
; цикл поиска шаблона  
BB:     xor AX, AX
    mov AX, __num1[DI]  ; в АL занести текущий символ
    cmp AX, __num2[SI]  ; сравнение символа строки и шаблона
    je TY               ; символы равны
    mov __FLAG, 0       ; символы не равны
    mov __COUNT, 0      ; обнуляем количество равных символов
    mov SI, 4           ; возвращаемся в начало шаблона
    jmp CONTINUE        ; перейти по метке
 
TY:
    mov __FLAG, 1           ; символы равны
    add SI,word ptr  2              ; переходим к следующему символу шаблона
    inc __COUNT         ; увеличиваем кол-во проверенных символов
    mov AX, __num2 + 1; в AL занести длину шаблона
    cmp __COUNT, AX     ; сравниваем длину шаблона и кол-во проверенных символов
    je GO               ; если нашли совпадение, то выходим их цикла
 
CONTINUE:
    add  DI, word ptr 2             ; переходим к следующему символу строки
    loop BB             ; переход на следующую итерацию
 
GO:
    cmp __FLAG, 1
    je YESS
    jmp NOO
YESS:   
    inc DX          ; наращиваем количество повторений одной строки в другой
    xor SI, SI          ; очистить регистр SI
    mov SI, 4           ; в SI занести смещение в шаблоне
    add DI, word ptr 2              ; переходим к следующему символу строки
    dec CX
    cmp CX, word ptr 0
    je BB
NOO:
    xor SI, SI          ; очистить регистр SI
    mov SI, 4           ; в SI занести смещение в шаблоне
    mov DI, word ptr 2
    dec CX              ; переходим к следующему символу строки
    cmp CX, word ptr 0
    je BB
; конец цикла 
 
StrFindRet:
pop CX              
pop DI SI               ; восстанавливаем значения регистров 
pop BP
ret __ArgSize           ; убираем параметры
StrFind endp

end                     ; конец программы

Решение задачи: «Создать подпрограмму, определяющую, содержится ли одна заданная строка в другой заданной строке»

textual
Листинг программы
locals __       ; определение префикса локальных переменных
.model SMALL    ; определение модели памяти
stack 200h      ; задаем размер стека - 512 байт
 
dataseg         ; определяем сегмент данных
COUNT_STR dw 0  ; число введенных строк
 
INFO_MESSAGE    db 0AH, 0DH
                db "Enter two lines"
                db 0AH, 0DH, '$'
 
INVITE_1        db 0Ah, 0Dh
                db "Enter the first line: $"
INVITE_2        db 0Ah, 0Dh
                db "Enter the second line: $"
 
INVITE_RESULT_1 db 0Ah, 0Dh
                db "YES! "
                db 0Ah, 0Dh, '$'
                
INVITE_RESULT_2 db 0Ah, 0Dh
                db "NO! "
                db 0Ah, 0Dh, '$'
 
 
PRESS           db 0Ah, 0Dh
                db "Exit - any $"
 
STR_1           db 80, ?, 82 dup ( ? )
STR_2           db 80, ?, 82 dup ( ? )
BUFFER          db 80, ?, 82 dup ( ? )
 
REPETITION      dw 0h                   ; количество одной строки в другой
 
 
codeseg                     ; определение сегмента кода
startupcode                 ; установление регистров DS и SS
 
lea DX, INFO_MESSAGE        ; в DX занести адрес строки
mov AH, 09h                 ; в АН занести номер функции
int 21h                     ; вызов прерывания
 
;ввод строк с клавиатуры 
 
InputStr:
    lea DX, INVITE_1        ; в DX занести адрес строки
    mov AH, 09h             ; в АН занести номер функции
    int 21h                 ; вызов прерывания
    lea DX, STR_1           ; в DX занести буфер для ввода
    mov AH, 0Ah             ; в АН занести номер функции
    int 21h                 ; вызов прерывания
    lea DX, INVITE_2        ; в DX занести адрес строки
    mov AH, 09h             ; в АН занести номер функции
    int 21h                 ; вызов прерывания
    lea DX, STR_2           ; в DX занести буфер для ввода
    mov AH, 0Ah             ; в АН занести номер функции
    int 21h                 ; вызов прерывания
 
 
FIND:
    ;;;; ПОИСК ;;;;
    lea DI,STR_1 
    lea SI,STR_2
    lea DX,REPETITION
 
    push DX
    push SI
    push DI 
    
    call StrFind    ; вызываем подпрограмму
    cmp DX, word ptr 0
    je NO
YES:
    lea DX, INVITE_RESULT_1 ; в DX занести адрес строки
    mov AH, 09h ; в АН занести номер функции 
    int 21h ; вызов прерывания
    jmp metka1
NO:
    lea DX, INVITE_RESULT_2 ; в DX занести адрес строки
    mov AH, 09h ; в АН занести номер функции 
    int 21h ; вызов прерывания              
    
metka1:
; пауза перед выходом из программы 
    lea DX, PRESS ; в DX занести адрес строки
    mov AH, 09h ; в АН занести номер функции 
    int 21h ; вызов прерывания
    mov AH, 08h ; в АН занести номер функции
    int 21h ; вызов прерывания
 
QUIT:
exitcode 0                  ; вернуть в ОС код возврата - 0
 
    
; подпрограмма поиска одной строки в другой
            ; аргументы 
            ; __num1 - индекс первой строки;
            ; __num2 - индекс второй строки;
            ; выходные значения 
            ; результат в REPETITION
 
StrFind proc near
 arg __num1:word, __num2:word,__num3:word = __ArgSize
 local  __FLAG: byte, __COUNT: word, __COUNT_REPEAT:word = __LocSize
 
push BP                     ; сохранить значение базового указателя
mov BP, SP                  ; базовому указателю присваиваем указатель стека
push SI DI                  ; сохраняем значение регистров SI и DI
;push CX
 
mov     SI, 4
mov     DI, 4
 
mov __FLAG, 0
mov __COUNT, 0
mov __COUNT_REPEAT, 0
 
mov CH, 0
mov CL, 1[BX]
mov DI, __num1
add DI, 2 ;
mov SI, __num2
add SI, 2 ;
 
mov BX, __num3
 
; цикл поиска шаблона  
BB: 
    mov AL, [DI]        ; в АL занести текущий символ
    cmp AL, [SI]        ; сравнение символа строки и шаблона
    je TY               ; символы равны
    mov __FLAG, 0       ; символы не равны
    mov __COUNT, 0      ; обнуляем количество равных символов
    mov SI, 4           ; возвращаемся в начало шаблона
    jmp CONTINUE        ; перейти по метке
 
TY:
    mov __FLAG, 1       ; символы равны
    add SI,word ptr  2  ; переходим к следующему символу шаблона
    inc __COUNT         ; увеличиваем кол-во проверенных символов
    mov AH, 0
    mov AL, 1[SI]
                        ;mov AX, __num2 + 1 ; в AL занести длину шаблона
    cmp __COUNT, AX     ; сравниваем длину шаблона и кол-во проверенных символов
    je GO               ; если нашли совпадение, то выходим их цикла
 
CONTINUE:
    add  DI, word ptr 2 ; переходим к следующему символу строки
    loop BB             ; переход на следующую итерацию
 
GO:
    cmp __FLAG, 1
    je YESS
    jmp NOO
YESS:   
    inc __COUNT_REPEAT      ; наращиваем количество повторений одной строки в другой
    xor SI, SI              ; очистить регистр SI
    mov SI, 4               ; в SI занести смещение в шаблоне
    add DI, word ptr 2      ; переходим к следующему символу строки
    dec CX
    cmp CX, word ptr 0
    je BB
NOO:
    xor SI, SI          ; очистить регистр SI
    mov SI, 4           ; в SI занести смещение в шаблоне
    mov DI, word ptr 2
    dec CX              ; переходим к следующему символу строки
    cmp CX, word ptr 0
    je BB
; конец цикла 
 
mov word ptr [BX], __COUNT_REPEAT
 
StrFindRet:
pop CX              
pop DI SI               ; восстанавливаем значения регистров 
pop BP
ret __ArgSize           ; убираем параметры
StrFind endp
 
 
 
end                     ; конец программы

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.25 из 5
Похожие ответы