Ввести строку. Вывести слова, содержащие букву «о» и количество таких слов - Assembler

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

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

Здравствуйте, есть задание по написанию программы на ассемблере для консоли. Перелазила почти весь Интернет, просмотрела ваш форум, но ничего не помогло. Нашла кусочек программы, разбиралась в нем часов 5, пыталась переделать под свою, но тоже ничего не вышло. Вот кусочек кода:
 m2: 
    mov eax, Len  ;длину строки в счетчик
    lea ebx, BUF  ;начало строки в ebx
    lea edx, Rez ;начало строки в edx   
    dec ebx
m3:
    cmp eax, 2   ;не равен ли счетчик 0
    je FAILED     ;равен=> к метке exit
    dec eax      ;ecx - 1 (смещение)  
    inc ebx     ;ebx + 1 (смещение)
    mov al, [ebx]    ;в регистр содержимое ячейки из строки  
    cmp al, 'r' ;сравниваем с "r"
    je m4       ;равен,переходим к метке m4
    
    cmp al, ' ' ;сравниваем с пробелом
    je m3       ;равен пробелу,переходим к метке m3
    
    inc ebx      ;перешли к след элементу строки
    cld         ;cбросили флаг,идем слева направо
    mov al, ' ' ;в регистр записываем пробел
    mov edi, ebx  ;в edi записываем ebx
repne scasb       ;пока не встретится пробел сравниваем
    dec edi ;    ;нашли пробел,получили его смещение
    mov ebx, edi  ;записали в ebx текущую позицию пробела    
    jmp m3      ;в метку m3

m4:         ;записываем слово начинающееся на букву 'r' в строку Rez    
    mov esi, ebx  ;для lodsb
    mov edi, edx  ;для stosb
    cld
n1:  
    lodsb       ;из esi символ в al
    mov ebx, edi
    cmp al, ' '
    je m5       ;если дошли до пробела, то слово закончилось,в метку m5
    stosb       ;символ al в edi        
    loop n1     ;цикл
m5: 
    inc COUNT   ;увеличили переменную, отвеч. за кол-во слов
    stosb       ;запишем пробел в строку rez чтобы слова были разделены 
    mov edx, edi  ;текущее смещение в dx
    dec eax      ;уменьшили счетчик
    jmp m3
Не понимаю, как организовать поиск пробела и переход к следующему слову (строки 18-25), а также как организовать в строках 11-13 поиск символа в слове не с начала строки, а во всем слове. Помогите, пожалуйста. Совсем потеряла надежду разобраться

Решение задачи: «Ввести строку. Вывести слова, содержащие букву «о» и количество таких слов»

textual
Листинг программы
;FASM-code...
format PE Console 4.0
include 'win32a.inc'
entry start
 
section '.data' data readable writeable
 
mes       db  'Type string: '
stdOut    dd  0                ;место под хэндлы ввода-вывода
stdIn     dd  0                ;
size      dd  0                ;длина строки
buff      db  128 dup(0)       ;буфер для строки (макс.128-символов)
table     dd  32 dup(0)        ;таблица с адресами начала слов (макс.16-слов)
 
section '.text' code readable executable
 
start:  invoke  GetStdHandle, -11     ;получаем хэндлы консоли
        mov     [stdOut], eax         ;(монитор
        invoke  GetStdHandle, -10     ;   ..и клава)
        mov     [stdIn], eax
 
;------ Запрос на ввод, и вводим строку
        invoke  WriteConsoleA, [stdOut], mes, 13,0,0
        invoke  ReadConsoleA, [stdIn], buff, 128, size, 0
 
;------ Создаём таблицу адресов начала и длины каждого слова в строке
        mov     edi,buff              ; адрес строки
        mov     ecx,[size]            ; её длина
        xor     esi,esi               ; смещение в таблице
        mov     ebp,1                 ; счётчик слов (1 в дефолте)
        mov     al,' '                ; что искать
@findSpace:                           ;
        mov     ebx,ecx               ; BX = длина от начала
        mov     dword[table+esi],edi  ; запишем в таблицу адрес начала слова
        add     si,4                  ;    ..(шаг вправо в таблице)
        repne   scasb                 ; искать пробел в строке!
        sub     ebx,ecx               ; вычисляем длину слова
        mov     dword[table+esi],ebx  ; запишем её в таблицу
        add     si,4                  ;    ..(шаг вправо)
        inc     ebp                   ; увеличиваем счётчик слов
        or      ecx,ecx               ; всю строку проверили?
        jnz     @findSpace            ; переход, если нет..
 
;------ Поиск в каждом слове символа(о), и вывод этого слова на консоль
; адрес слов и их длину будем брать из таблицы.
; BP = кол-во указателей в таблице (общее кол-во слов в строке).
        mov     esi,table             ; адрес таблицы в SI
@findChar:
        dec     ebp                   ; все слова проверили?
        jz      @exit                 ; выйти, если да..
        lodsd                         ;
        xchg    edi,eax               ; EDI = адрес начала очередного слова
        lodsd                         ;
        xchg    ecx,eax               ; ECX = длина этого слова
        push    ecx edi               ; запомнить для вывода на консоль!
                                      ;
        mov     al,'o'                ; что искать в слове..
        repne   scasb                 ; поиск!
        or      cx,cx                 ; запомним результат поиска во-флагах
        pop     edi ecx               ; снимаем со-стека атрибуты слова
        jz      @findChar             ; проверить флаги!
                                      ;   ..следующее слово (если нет результата).
 
invoke  WriteConsoleA, [stdOut],edi,ecx,0,0  ; иначе: отправляем атрибуты слова,
        jmp     @findChar                    ; ..в параметры функции вывода на экран.
 
@exit:  invoke  ExitProcess, 0        ; выход из программы!
;---------------------------------------------------------------------------
 
section '.idata' import data readable
 
  library kernel, 'KERNEL32.DLL'
  import kernel,\
       WriteConsoleA,'WriteConsoleA',\      ; API для импорта из кернел32.
       ReadConsoleA,'ReadConsoleA',\
       GetStdHandle,'GetStdHandle',\
       ExitProcess, 'ExitProcess'

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

Код написан на ассемблере и решает задачу поиска слов, содержащих букву о, и вывода этих слов вместе с их количеством. Список действий:

  1. Получение хэндлов для консоли и клавиатуры.
  2. Запрос на ввод строки.
  3. Создание таблицы адресов начала и длины каждого слова в строке.
  4. Поиск в каждом слове символа о и вывод этого слова на консоль.
  5. В конце программы выводится количество найденных слов.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

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

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