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

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

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

Здравствуйте, есть задание по написанию программы на ассемблере для консоли. Перелазила почти весь Интернет, просмотрела ваш форум, но ничего не помогло. Нашла кусочек программы, разбиралась в нем часов 5, пыталась переделать под свою, но тоже ничего не вышло. Вот кусочек кода:
Листинг программы
  1. m2:
  2. mov eax, Len ;длину строки в счетчик
  3. lea ebx, BUF ;начало строки в ebx
  4. lea edx, Rez ;начало строки в edx
  5. dec ebx
  6. m3:
  7. cmp eax, 2 ;не равен ли счетчик 0
  8. je FAILED ;равен=> к метке exit
  9. dec eax ;ecx - 1 (смещение)
  10. inc ebx ;ebx + 1 (смещение)
  11. mov al, [ebx] регистр содержимое ячейки из строки
  12. cmp al, 'r' ;сравниваем с "r"
  13. je m4 ;равен,переходим к метке m4
  14. cmp al, ' ' ;сравниваем с пробелом
  15. je m3 ;равен пробелу,переходим к метке m3
  16. inc ebx ;перешли к след элементу строки
  17. cld ;cбросили флаг,идем слева направо
  18. mov al, ' ' регистр записываем пробел
  19. mov edi, ebx edi записываем ebx
  20. repne scasb ;пока не встретится пробел сравниваем
  21. dec edi ; ;нашли пробел,получили его смещение
  22. mov ebx, edi ;записали в ebx текущую позицию пробела
  23. jmp m3 метку m3
  24.  
  25. m4: ;записываем слово начинающееся на букву 'r' в строку Rez
  26. mov esi, ebx ;для lodsb
  27. mov edi, edx ;для stosb
  28. cld
  29. n1:
  30. lodsb ;из esi символ в al
  31. mov ebx, edi
  32. cmp al, ' '
  33. je m5 ;если дошли до пробела, то слово закончилось,в метку m5
  34. stosb ;символ al в edi
  35. loop n1 ;цикл
  36. m5:
  37. inc COUNT ;увеличили переменную, отвеч. за кол-во слов
  38. stosb ;запишем пробел в строку rez чтобы слова были разделены
  39. mov edx, edi ;текущее смещение в dx
  40. dec eax ;уменьшили счетчик
  41. jmp m3
Не понимаю, как организовать поиск пробела и переход к следующему слову (строки 18-25), а также как организовать в строках 11-13 поиск символа в слове не с начала строки, а во всем слове. Помогите, пожалуйста. Совсем потеряла надежду разобраться

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

textual
Листинг программы
  1. ;FASM-code...
  2. format PE Console 4.0
  3. include 'win32a.inc'
  4. entry start
  5.  
  6. section '.data' data readable writeable
  7.  
  8. mes       db  'Type string: '
  9. stdOut    dd  0                ;место под хэндлы ввода-вывода
  10. stdIn     dd  0                ;
  11. size      dd  0                ;длина строки
  12. buff      db  128 dup(0)       ;буфер для строки (макс.128-символов)
  13. table     dd  32 dup(0)        ;таблица с адресами начала слов (макс.16-слов)
  14.  
  15. section '.text' code readable executable
  16.  
  17. start:  invoke  GetStdHandle, -11     ;получаем хэндлы консоли
  18.         mov     [stdOut], eax         ;(монитор
  19.         invoke  GetStdHandle, -10     ;   ..и клава)
  20.         mov     [stdIn], eax
  21.  
  22. ;------ Запрос на ввод, и вводим строку
  23.         invoke  WriteConsoleA, [stdOut], mes, 13,0,0
  24.         invoke  ReadConsoleA, [stdIn], buff, 128, size, 0
  25.  
  26. ;------ Создаём таблицу адресов начала и длины каждого слова в строке
  27.         mov     edi,buff              ; адрес строки
  28.         mov     ecx,[size]            ; её длина
  29.         xor     esi,esi               ; смещение в таблице
  30.         mov     ebp,1                 ; счётчик слов (1 в дефолте)
  31.         mov     al,' '                ; что искать
  32. @findSpace:                           ;
  33.         mov     ebx,ecx               ; BX = длина от начала
  34.         mov     dword[table+esi],edi  ; запишем в таблицу адрес начала слова
  35.         add     si,4                  ;    ..(шаг вправо в таблице)
  36.         repne   scasb                 ; искать пробел в строке!
  37.         sub     ebx,ecx               ; вычисляем длину слова
  38.         mov     dword[table+esi],ebx  ; запишем её в таблицу
  39.         add     si,4                  ;    ..(шаг вправо)
  40.         inc     ebp                   ; увеличиваем счётчик слов
  41.         or      ecx,ecx               ; всю строку проверили?
  42.         jnz     @findSpace            ; переход, если нет..
  43.  
  44. ;------ Поиск в каждом слове символа(о), и вывод этого слова на консоль
  45. ; адрес слов и их длину будем брать из таблицы.
  46. ; BP = кол-во указателей в таблице (общее кол-во слов в строке).
  47.         mov     esi,table             ; адрес таблицы в SI
  48. @findChar:
  49.         dec     ebp                   ; все слова проверили?
  50.         jz      @exit                 ; выйти, если да..
  51.         lodsd                         ;
  52.         xchg    edi,eax               ; EDI = адрес начала очередного слова
  53.         lodsd                         ;
  54.         xchg    ecx,eax               ; ECX = длина этого слова
  55.         push    ecx edi               ; запомнить для вывода на консоль!
  56.                                       ;
  57.         mov     al,'o'                ; что искать в слове..
  58.         repne   scasb                 ; поиск!
  59.         or      cx,cx                 ; запомним результат поиска во-флагах
  60.         pop     edi ecx               ; снимаем со-стека атрибуты слова
  61.         jz      @findChar             ; проверить флаги!
  62.                                       ;   ..следующее слово (если нет результата).
  63.  
  64. invoke  WriteConsoleA, [stdOut],edi,ecx,0,0  ; иначе: отправляем атрибуты слова,
  65.         jmp     @findChar                    ; ..в параметры функции вывода на экран.
  66.  
  67. @exit:  invoke  ExitProcess, 0        ; выход из программы!
  68. ;---------------------------------------------------------------------------
  69.  
  70. section '.idata' import data readable
  71.  
  72.   library kernel, 'KERNEL32.DLL'
  73.   import kernel,\
  74.        WriteConsoleA,'WriteConsoleA',\      ; API для импорта из кернел32.
  75.        ReadConsoleA,'ReadConsoleA',\
  76.        GetStdHandle,'GetStdHandle',\
  77.        ExitProcess, 'ExitProcess'

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

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

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

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


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

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

5   голосов , оценка 3.6 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы