Поиск подстроки в строке - 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
Объяснение кода листинга программы
Код выполняет поиск подстроки в строке. Вот список действий:
- Счетчик символов в строке с коррекцией регистра DI после строковых команд
- Подсчет подстроки
- Сравнение подстроки со строкой (SI и DI)
- Преобразование и вывод на экран Список переменных:
- S - основная строка
- So - подстрока
- LenS - длина основной строки
- LenSo - длина подстроки
Пояснения к коду:
- После выполнения команд с использованием регистров SI и DI, значение регистра DI корректируется.
- Подстрока читается с помощью команды lodsb, которая читает первый символ из подстроки в AL (si).
- Для сравнения строк используются команды scasb и cmpsb.
- После выполнения команды div в процедуре Len, частное от деления сохраняется в памяти, а остаток отбрасывается.
- Для вывода найденной подстроки на экран используется команда int 21h.