Число палиндромов в строке - 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
Объяснение кода листинга программы
Код написан на ассемблере и выполняет следующую задачу: проверка строки на симметричность (палиндром). Список функций и переменных:
- IsPalindrome - функция, которая проверяет строку на симметричность (палиндром)
- Process - функция, которая обрабатывает входные данные и выводит результат
- aszMsgInstant, aszMsgResult, aszInteger, aszString - строки, которые используются для вывода сообщений и результатов
- hConsoleOutput, hConsoleInput, Result, Buffer, BufLen - переменные, которые используются для работы с консолью и хранения результатов Список действий:
- Получение описателей ввода и вывода консоли
- Очистка экрана
- Вывод сообщений и исходных данных
- Обработка входных данных и вывод результата
- Ожидание нажатия ENTER
- Завершение программы