Поиск подстроки в строке - Assembler

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

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

здравствуйте, помогите пожалуйста в написании программы под TASM. задача: Найти индекс первого вхождения подстроки S0 в строку S. честно говоря со строками в asm'е работать толком не умею, поэтому прошу вашей помощи.

Решение задачи: «Поиск подстроки в строке»

textual
Листинг программы
;TASM, COM - файл
;tasm.exe /m
;tlink.exe /t /x
;
.model tiny
.code
.386
org 100h
start:
;Подсчет символов в строке с коррекцией регистра DI после строковых команд
    lea di,S
    mov si,di   ;si потом понадобится для ввода первого символа подстроки
    mov dx,di   ;сохранить адрес строки
push di
    call Len    ;подсчет
    mov [LenS],di   ;результат
;Подсчет подстроки
    lea di,So
    mov si,di
    call Len
    dec di      ;еще одна коррекция после lodsb
    mov [LenSo],di
 
    lodsb       ;читать первый символ из подстроки в AL (si)
    mov bx,si   ;адес второго символа будет нужен для сравнения строк
pop di          ;адрес строки
m1:
    mov si,bx
    mov cx,[LenS]
    repne scasb ;искать первый символ из AL в строке (di)
    jnz short exit
 
    mov [LenS],cx   ;остаток символов в строке
    mov cx,[LenSo]  ;число символов в подстроке
    repe cmpsb  ;сравнить подстроку со строкой (SI и DI)
    jnz short m1    ;нет совпадений
    sub di,dx   ;совпало, разница начала строки и конец
    sub di,[LenSo]  ;и еще минус подстрока
    mov ax,di   ;индекс в строке
 
;Преобразование и вывод на экран
    xor     cx, cx
    mov     bx, 10 ; основание сс. 10 для десятеричной и т.п.
oi2:
    xor     dx,dx
    div     bx
; Делим число на основание сс. В остатке получается последняя цифра.
; Сразу выводить её нельзя, поэтому сохраним её в стэке.
    push    dx
    inc     cx
; А с частным повторяем то же самое, отделяя от него очередную
; цифру справа, пока не останется ноль, что значит, что дальше
; слева только нули.
    test    ax, ax
    jnz     oi2
; Теперь приступим к выводу.
    mov     ah, 02h
oi3:
    pop     dx
    add     dl, '0'
    int     21h
; Повторим ровно столько раз, сколько цифр насчитали.
    loop    oi3
 
exit:
    mov ah,0
    int 16h
 
    ret
;------------------
Len proc    near
    mov al,0    ;искать 0
    mov bx,di   ;сохранить начальный адрес строки
    mov cx,-1   ;максимально возможная длина строки 0FFFFh
    repne scasb ;искать
    sub di,bx   ;разница адресов между началом строки и
            ;найденым 0 = длина строки + 1
    dec di      ;DI=DI-1=длина строки
    ret
Len endp
;------------------- 
S       db     '123456789opata*opa',0    ;основная строка
So      db     'opa',0           ; подстрока
LenS    dw  ?
LenSo   dw  ?
 
    end start

Объяснение кода листинга программы

Код выполняет поиск подстроки в строке. Вот список действий:

  1. Счетчик символов в строке с коррекцией регистра DI после строковых команд
  2. Подсчет подстроки
  3. Сравнение подстроки со строкой (SI и DI)
  4. Преобразование и вывод на экран Список переменных:
  5. S - основная строка
  6. So - подстрока
  7. LenS - длина основной строки
  8. LenSo - длина подстроки Пояснения к коду:
    • После выполнения команд с использованием регистров SI и DI, значение регистра DI корректируется.
    • Подстрока читается с помощью команды lodsb, которая читает первый символ из подстроки в AL (si).
    • Для сравнения строк используются команды scasb и cmpsb.
    • После выполнения команды div в процедуре Len, частное от деления сохраняется в памяти, а остаток отбрасывается.
    • Для вывода найденной подстроки на экран используется команда int 21h.

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

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