Замена символов - Assembler

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

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

Помогите разобраться. Вот задание лабы: Задано текст із 20 символів. Визначити кількість повторень поєднань "ОР" в тексті і замінити такі повторення символом "!". Подскажите как сделать замену символов. Есть код программы замены символов, но проблема в том, что заменяется только первый встретившийся нужный символ. .386 ; директива визначення типу мікропроцесора .model flat,stdcall ; завдання лінійної моделі пам’яті та угоди ОС Windows option casemap:none ; відмінність малих та великих літер include \masm32\include\windows.inc ; файли структур, констант … include \masm32\include\kernel32.inc ; файли систем. функцій застосувань… include \masm32\include\user32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib .data ; директива визначення даних titl db " Результат ",0 ; назва вікна mas1 db 'assembler' ; масив байтів із символами коду ASCII len equ $-mas1 ; визначення кількості байтів в масиві mas1 buf db ?,0 ; буфер виведення повідомлення .code ; директива початку сегмента даних _st: ; мітка початку програми з ім’ям _st lea edi, mas1 ; завантаження адреси масиву mas1 mov al, 's' ; завантаження символу ‘f’ mov ecx, len ; встановити в лічильник max значення літер cld ; напрям – вгору repne scasb ; повторювати, поки не буде дорівнювати dec edi ; знайдений: декременувати DI MOV BYTE PTR[edi],' ' invoke MessageBox, \ ; АРІ-функція виведення спрощеного віконця NULL, \ ; hwnd – ідентифікатор вікна addr mas1, \ ; адреса рядка, яка містить текст повідомлення addr titl, \ ; адреса рядка, яка містить заголовок повідомлення MB_OK ; вигляд діалогового вікна – одна кнопка ОК invoke ExitProcess,0 ; виклик процедури повернення керування ; ОС Windows та визволення ресурсів end _st ; директива закінчення програми з ім’ям _st

Решение задачи: «Замена символов»

textual
Листинг программы
format PE console
include 'win32a.inc'
 
        mov     esi,ssk
        mov     edi,sk
        mov     ecx,[qcsk]
        sub     ecx,[qcssk]
        inc     ecx
        mov     ebx,0
mRun:
 
        push    esi
        push    edi
        push    ecx
        mov     ecx,[qcssk]
        mov     al,1
mCompare:
        mov     ah,[edi]
        cmp     [esi],ah
        je      mEqual
        mov     al,0
        jmp     mCompareExit
mEqual:
        inc     esi
        inc     edi
        loop    mCompare
        inc     ebx
mCompareExit:
        pop     ecx
        pop     edi
        pop     esi
 
        cmp     al,1
        jne     mNot
        push    esi
        push    edi
        push    ecx
        mov     esi,edi
        inc     esi
        repne   movsb
        pop     ecx
        pop     edi
        pop     esi
        mov     [edi],byte 33
        dec     ecx
mNot:
 
        inc     edi
        cmp     ecx,0
        jne     mEcxNZ
        inc     ecx
mEcxNZ:
        loop    mRun
 
        invoke  ExitProcess,0
 
sk      db 'OPcdefOPxyzOP'
qcsk    dd $-sk
ssk     db 'OP'
qcssk   dd $-ssk
 
include 'API\kernel32.inc'
 
data import
 
        library kernel32,'KERNEL32.DLL'
 
end data

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

Список элементов кода:

  1. Переменные:
    • esi, ssk
    • edi, sk
    • ecx, [qcsk]
    • ebx, 0
  2. Циклы:
    • while (1) {...} - mRun
    • while (esi < [qcssk]) {...} - mCompare
    • while (ecx != 0) {...} - mEcxNZ
  3. Команды:
    • mov
    • push
    • pop
    • cmp
    • jne
    • inc
    • repne
    • movsb
    • invoke
    • db (данные, представленные в виде строки)
    • dd (данные, представленные в виде двойного слова)
    • library (импорт функций из библиотеки kernel32.dll)
  4. Значения переменных:
    • ssk содержит 'OP'
    • qcssk содержит '-ssk'
    • qcsk содержит 'OPcdefOPxyzOP'
    • ebx содержит 0
    • ecx содержит количество символов, которые нужно заменить
    • edi содержит индекс текущего символа для замены
    • esi содержит индекс последнего символа для замены
    • al содержит 0 или 1
  5. Последовательность выполнения команд:
    • Переменная ecx инициализируется значением из qcsk
    • Выполняется цикл mCompare, пока не будет найдено соответствие символа из ssk
    • Если символ найден, индексы esi и edi увеличиваются, и выполняется цикл mRun
    • Если символ не найден, выполняется цикл mEcxNZ, пока ecx не станет равным 0
    • Если ecx не равно 0, вызывается функция ExitProcess с аргументом 0
    • Если ecx равно 0, вызывается функция ExitProcess с аргументом 0

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

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