Число палиндромов в строке - Assembler

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

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

Добрый день! Просьба помочь с задачей на MASM32: процедура определяет количество слов в строке, являющихся палиндромами. Вход: DS:ESI - адрес строки, заканчивающейся символом с кодом 0, ECX - количество слов в строке, удовлетворяющие заданному условию. В начале и в конце строки могут быть пробелы плюс может быть разделение слов пробелами. Слово, состоящее из одной буквы - палиндром Нашел такой код, но он для одного слова и на .286 (нужен .386)
.model tiny
.code
.286
org 100h
start:  mov ax,3
    int 10h; стираем с экрана
    mov ah,9
    mov dx,offset msg
    int 21h
    mov ah,0Ah
    mov dx,offset buffer
    int 21h
    mov ah,9
    mov dx,offset msg1-3
    int 21h
    mov bh,0
    mov bl,buffer+1
    mov cx,bx
    dec bx
    mov si,offset buffer+2
    add bx,si
    cmp bx,si
    je exit
a1: lodsb
    cmp al,[bx]
    jne exit1
    dec bx
    loop a1
exit:   mov dx,offset msg1+2
    jmp a2
exit1:  mov dx,offset msg1
a2: mov ah,9
    int 21h
    mov ah,0; ждем пока не нажмут на клавиатуру
    int 16h
    ret; выходим из программы
msg db "Набери слово и нажми Enter",0Dh,0Ah,'$'
msg1 db "непалиандром$"
buffer db 255,?,255 dup(?)
end start

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

textual
Листинг программы
.686
.model flat, stdcall
option casemap :none
 
        include \masm32\include\windows.inc
 
        include \masm32\include\user32.inc
        include \masm32\include\kernel32.inc
        include \masm32\include\masm32.inc
 
        includelib \masm32\lib\user32.lib
        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\masm32.lib
.data
        aszMsgInstant   db      0Dh, 0Ah, 'Instant:', 0Dh, 0Ah, 0
        aszMsgResult    db      0Dh, 0Ah, 'Result:', 0Dh, 0Ah, 0
        aszInteger      db      '%4d', 0
        aszPressEnter   db      0Dh, 0Ah, 0Dh, 0Ah, "Press ENTER to exit", 0
        Delimiter       db      ' '
        aszString       db      '    99   ghj tyt tyyt t    ui    uou hj', 0
.data?
        hConsoleOutput  HANDLE  ?
        hConsoleInput   HANDLE  ?
        Result          dd      ?
        Buffer          db      1024 dup(?)
        BufLen          dd      ?
 
.code
 
;Проверка строки на симметричность (палиндром)
;на входе:
;  lpString - указатель на первый символ строки
;  uiLenString - длина строки
;на выходе:
;  eax - 0 - не палиндром
;      - 1 - палиндром
IsPalindrome    proc    lpString:DWORD, uiLenString:DWORD
        push    esi
        push    edi
        push    ebx
        push    ecx
        push    edx
 
        mov     ebx,    1               ;да, пока палиндром
        mov     esi,    [lpString]      ;esi - на начало слова
        mov     ecx,    [uiLenString]   ;ecx - количество символов
        mov     edi,    esi             ;edi - на конец слова
        add     edi,    ecx
        dec     edi
        shr     ecx,    1
        jecxz   @@Exit
        xor     edx,    edx
        @@For:
                mov     al,     [esi]
                cmp     al,     [edi]
                cmovnz  ebx,    edx
                jnz     @@Exit
                inc     esi
                dec     edi
        loop    @@For
 
@@Exit:
        mov     eax,    ebx
 
        pop     edx
        pop     ecx
        pop     ebx
        pop     edi
        pop     esi
        ret
IsPalindrome    endp
 
Process proc    lpString:DWORD
 
        xor     ebx,    ebx             ;нет палиндромов
 
        mov     esi,    [lpString]
        ;пропуск разделителей
        @@SkipDelimiters:
                lodsb
                cmp     al,     [Delimiter]
        je      @@SkipDelimiters
        or      al,     al
        jz      @@Exit
        ;выделение слова из строки
        mov     edi,    esi             ;(edi-1) - на начало слова
        @@ExtractWord:
                cmp     al,     0
                je      @@Break
                cmp     al,     [Delimiter]
                je      @@Break
 
                lodsb
        jmp     @@ExtractWord
@@Break:
        mov     ecx,    esi             ;(esi-1) - на последнюю букву слова
        sub     ecx,    edi             ;ecx - длина слова
        dec     edi                     ;edi - на начало слова
        push    eax
        invoke  IsPalindrome,   edi, ecx
        add     ebx,    eax
        pop     eax
        or      al,     al
        jnz     @@SkipDelimiters
@@Exit:
        mov     eax,    ebx
        ret
Process endp
 
main    proc
 
        ; получение описателей ввода и вывода консоли
        invoke  GetStdHandle,   STD_INPUT_HANDLE
        mov     hConsoleInput,  eax
 
        invoke  GetStdHandle,   STD_OUTPUT_HANDLE
        mov     hConsoleOutput, eax
 
        invoke  ClearScreen
 
        ;вывод исходных данных
        invoke  WriteConsole, hConsoleOutput, ADDR aszMsgInstant,\
                LENGTHOF aszMsgInstant - 1, ADDR BufLen, NULL
        invoke  WriteConsole, hConsoleOutput, ADDR aszString,\
                LENGTHOF aszString - 1, ADDR BufLen, NULL
        ;обработка
        invoke  Process,        ADDR aszString
        mov     [Result],       eax
        ;вывод результата
        invoke  WriteConsole, hConsoleOutput, ADDR aszMsgResult,\
                LENGTHOF aszMsgResult - 1, ADDR BufLen, NULL
        invoke  wsprintf, ADDR Buffer, ADDR aszInteger, [Result]
        invoke  StrLen, ADDR Buffer
        mov     [BufLen],       eax
        invoke  WriteConsole, hConsoleOutput, ADDR Buffer,\
                BufLen, ADDR BufLen, NULL
        ;ожидание нажатия ENTER
        invoke  WriteConsole, hConsoleOutput, ADDR aszPressEnter,\
                LENGTHOF aszPressEnter - 1, ADDR BufLen, NULL
        invoke  ReadConsole, hConsoleInput, ADDR Buffer,\
                LENGTHOF Buffer, ADDR BufLen, NULL
 
        invoke  ExitProcess, 0
main    endp
 
end     main

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

Код написан на ассемблере и выполняет следующую задачу: проверка строки на симметричность (палиндром). Список функций и переменных:

  1. IsPalindrome - функция, которая проверяет строку на симметричность (палиндром)
  2. Process - функция, которая обрабатывает входные данные и выводит результат
  3. aszMsgInstant, aszMsgResult, aszInteger, aszString - строки, которые используются для вывода сообщений и результатов
  4. hConsoleOutput, hConsoleInput, Result, Buffer, BufLen - переменные, которые используются для работы с консолью и хранения результатов Список действий:
  5. Получение описателей ввода и вывода консоли
  6. Очистка экрана
  7. Вывод сообщений и исходных данных
  8. Обработка входных данных и вывод результата
  9. Ожидание нажатия ENTER
  10. Завершение программы

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

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