Загрузка данных


_STACK segment para stack                              ; стек
        db 1024 dup(?)                                ; стек
_STACK ends

_DATA segment
        SourceLen equ 9                               ; длина исходной строки
        FindLen   equ 4                               ; длина искомой строки
        ReplLen   equ 4                               ; длина строки замены

        Source db 'HELLOWRLD'                         ; исходная строка
        FindStr db 'WRLD'                             ; что ищем
        ReplStr db 'EEEE'                             ; на что заменяем

        Result db SourceLen dup(?)                    ; результат
        CrLf db 0Dh, 0Ah, '$'                         ; перевод строки
_DATA ends

_TEXT segment
        assume cs:_TEXT, ds:_DATA, ss:_STACK

main proc
        mov ax, _DATA                                 ; адрес сегмента данных
        mov ds, ax                                    ; инициализация ds
        mov es, ax                                    ; инициализация es

        lea si, Source                                ; адрес source
        lea di, Result                                ; адрес result
        mov cx, SourceLen                             ; длина строки
        rep movsb                                     ; копирование source в result

        lea dx, Source                                ; адрес исходной строки
        mov cx, SourceLen                             ; длина исходной строки
        call ShowString                               ; вывод исходной строки
        mov ah, 09h                                   ; вывод строки $
        lea dx, CrLf                                  ; перевод строки
        int 21h                                       ; вызов dos

        lea dx, FindStr                               ; адрес искомой строки
        mov cx, FindLen                               ; длина искомой строки
        call ShowString                               ; вывод искомой строки
        mov ah, 09h                                   ; вывод строки $
        lea dx, CrLf                                  ; перевод строки
        int 21h                                       ; вызов dos

        mov cx, SourceLen - FindLen + 1               ; число позиций для поиска
        xor bx, bx                                    ; текущая позиция

SearchPos:
        push cx                                       ; сохранить счетчик

        lea si, Source                                ; адрес source
        add si, bx                                    ; смещение к позиции
        lea di, FindStr                               ; адрес findstr
        mov dx, FindLen                               ; длина сравнения

CmpLoop:
        cmp dx, 0                                     ; все символы совпали?
        je Found                                      ; да, найдено

        mov al, [si]                                  ; символ из source
        cmp al, [di]                                  ; сравнение с findstr
        jne NextPos                                   ; если не равно, дальше

        inc si                                        ; следующий символ
        inc di                                        ; следующий символ
        dec dx                                        ; уменьшить счетчик
        jmp CmpLoop                                   ; продолжить сравнение

NextPos:
        pop cx                                        ; восстановить счетчик
        inc bx                                        ; следующая позиция
        loop SearchPos                                ; продолжить поиск
        jmp ShowResult                                ; если не найдено, вывод result

Found:
        pop cx                                        ; убрать счетчик со стека

        lea di, Result                                ; адрес result
        add di, bx                                    ; позиция замены
        lea si, ReplStr                               ; адрес строки замены
        mov cx, ReplLen                               ; длина замены
        rep movsb                                     ; записать замену

ShowResult:
        lea dx, Result                                ; адрес результата
        mov cx, SourceLen                             ; длина результата
        call ShowString                               ; вывод результата
        mov ah, 09h                                   ; вывод строки $
        lea dx, CrLf                                  ; перевод строки
        int 21h                                       ; вызов dos

        mov ax, 4C00h                                 ; завершение программы
        int 21h                                       ; выход в dos
main endp

ShowString proc
        push ax                                       ; сохранить ax
        push cx                                       ; сохранить cx
        push dx                                       ; сохранить dx
        push si                                       ; сохранить si

        mov si, dx                                    ; si = адрес строки

PrintLoop:
        cmp cx, 0                                     ; конец строки?
        je ExitPrint                                  ; да, выход

        mov dl, [si]                                  ; текущий символ
        mov ah, 02h                                   ; вывод символа
        int 21h                                       ; вызов dos

        inc si                                        ; следующий символ
        dec cx                                        ; уменьшить счетчик
        jmp PrintLoop                                 ; продолжить

ExitPrint:
        pop si                                        ; восстановить si
        pop dx                                        ; восстановить dx
        pop cx                                        ; восстановить cx
        pop ax                                        ; восстановить ax
        ret                                           ; возврат
ShowString endp

_TEXT ends
end main