Guest User

Untitled

a guest
Dec 6th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.20 KB | None | 0 0
  1. ; Фомин Сергей, БПИ182-2
  2. ; Разработать программу, вычисляющую число букв латиницы и кириллицы в заданной ASCII-строке
  3.  
  4. format PE GUI 4.0 ; GUI-приложение для Windows (EXE-файл)
  5.  
  6. include "c:/emu8086/fasm/include/win32ax.inc" ; путь к подкаталогу /include/
  7.  
  8. .code ; начало секции кода
  9. start: ; точка старта программы
  10.  
  11. cinvoke GetCommandLine ; взяли командную строку
  12. mov [lpCommLine], eax ; запомнили указатель на командную строку в eax
  13. cinvoke sscanf, [lpCommLine], input_str, s1 ; из строки по формату читается s1, args[0] игнорируется
  14.  
  15. ; Проверка входной строки на вызов справки
  16. cinvoke strcmp, s1, "-h"
  17. cmp al, 0
  18. jnz not_h
  19. cinvoke MessageBox, 0, help_str, "Число букв латиницы и кириллицы", MB_OK
  20. cinvoke ExitProcess, 0
  21. not_h:
  22. cinvoke strcmp, s1, "-?"
  23. cmp al, 0
  24. jnz not_question
  25. cinvoke MessageBox, 0, help_str, "Число букв латиницы и кириллицы", MB_OK
  26. cinvoke ExitProcess, 0
  27. not_question:
  28.  
  29. ; Если входная строка пустая, то посчитаем символы для sample_str (занесём её в s1)
  30. cinvoke strcmp, s1, ""
  31. cmp al, 0
  32. jnz check_string
  33. cinvoke strcpy, s1, sample_str
  34.  
  35. check_string:
  36. push s1 ; записываем в стек нашу строку
  37. call strcntcyrillic ; вызываем strcntcyrillic для строки s1
  38. add esp, 4 ; восстановим стек после strcntcyrillic
  39. mov [latcnt], eax ; в eax хранится количество латинских букв
  40. mov [cyrcnt], ebx ; в ebx хранится количество букв кириллицы
  41.  
  42. cinvoke sprintf, res_str, form_str, s1, [latcnt], [cyrcnt] ; формируем строчку для вывода
  43. cinvoke MessageBox, 0, res_str, "Число букв латиницы и кириллицы", MB_OK ; выводим готовую строчку
  44.  
  45. cinvoke ExitProcess,0 ; выход из программы с кодом возврата 0
  46.  
  47. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  48. proc strcntcyrillic ; принимает со стека s1(стек не корректируется - соглашение cdecl)
  49. ; задействованы регистры eax, ebx, ecx, edx, esi
  50. ; на выходе в регистре eax хранится количество латинских букв, в ebx - букв кириллицы
  51.  
  52. mov esi, [esp+4] ; в esi запоминаем начало обрабатываемой строки
  53.  
  54. mov ecx, 0d ; ecx будет хранить количество латинских букв
  55. mov edx, 0d ; edx хранит количество букв кириллицы
  56.  
  57. mov esi, [esp+4] ; esi <- edi (начало сканирования строки)
  58.  
  59. retry: ; начало проверки очередного символа
  60.  
  61. mov al, [esi] ; копируем текущий символ в al для проверки, каким символом он является
  62.  
  63. ; если код символа лежит в пределах от 'A' (латиница) до 'Z' (латиница), то увеличиваем ecx (латиница)
  64. cmp al, 'A'
  65. jl not_add_big_lat
  66. cmp al, 'Z'
  67. jg not_add_big_lat
  68. inc ecx
  69. not_add_big_lat:
  70.  
  71. ; если код символа лежит в пределах от 'a' (латиница) до 'z' (латиница), то увеличиваем ecx (латиница)
  72. cmp al, 'a'
  73. jl not_add_small_lat
  74. cmp al, 'z'
  75. jg not_add_small_lat
  76. inc ecx
  77. not_add_small_lat:
  78.  
  79. ; если код символа лежит в пределах от 'А' (кириллица) до 'п' (кириллица), то увеличиваем ecx (латиница)
  80. cmp al, 'А'
  81. jl not_add_cyr_1
  82. cmp al, 'п'
  83. jg not_add_cyr_1
  84. inc edx
  85. not_add_cyr_1:
  86.  
  87. ; если код символа лежит в пределах от 'р' (кириллица) до 'я' (кириллица), то увеличиваем ecx (кириллица)
  88. cmp al, 'р'
  89. jl not_add_cyr_2
  90. cmp al, 'я'
  91. jg not_add_cyr_2
  92. inc edx
  93. not_add_cyr_2:
  94.  
  95. ; из-за разных кодировок 'ё', 'Ё' надо обрабатывать отдел
  96. ; проверка на 'ё'
  97. cmp al, 'ё'
  98. jnz not_add_small_yo
  99. inc edx
  100. not_add_small_yo:
  101.  
  102. ; проверка на 'Ё'
  103. cmp al, 'Ё'
  104. jnz not_add_big_yo
  105. inc edx
  106. not_add_big_yo:
  107.  
  108. cmp al, 0 ; проверка на нуль-терминатор
  109. jz str_end ; если 0, то выходим из цикла
  110. inc esi ; перемещаемся на следующий символ
  111. jmp retry ; переход в начало проверки следующего символа
  112.  
  113. str_end: ; по окончании цикла в ecx хранится количество латинских букв, в edx - кириллицы
  114. mov eax, ecx ; для красоты перенесём результат в более привычные регистры
  115. mov ebx, edx ; eax - количество латинских букв, ebx - кириллицы
  116.  
  117. ret
  118. endp ; конец процедуры
  119.  
  120. .data ; секция данных
  121. lpCommLine dd ? ; указатель на командную строку
  122. s1 db 4096 dup(?) ; обрабатываемая ASCII-строка (символ=байт)
  123. res_str db 4096 dup(?) ; строка для хранения готового отформатированного вывода
  124. form_str db "Исходная строка: ""%s""",10, 10, "Букв латиницы: %d", 10, "Букв кириллицы: %d", 10, 0 ; строка формата вывода
  125. input_str db "%*s %[^", 0, "]", 10, 0 ; Входная строчка (первый аргумента (расположение) игнорируется, второй - считывание всех символов до конца строки)
  126. help_str db "Данная программа принимает в качестве аргумента строчку и считает в ней количество букв кириллицы и количество букв латиницы.", 10, 0
  127. sample_str db "Съешь ещё этих мягких французских булок, да выпей же чаю. The quick brown fox jumps over the lazy dog.", 0 ; строка для примера
  128. latcnt dd 0 ; количество латинских букв
  129. cyrcnt dd 0 ; количество букв кириллицы
  130.  
  131. data import ; импортируем стандартные функции Windows
  132. library user32,'USER32.DLL', \
  133. msvcrt,'MSVCRT.DLL', \
  134. kernel32,'KERNEL32.DLL', \
  135. shell32,'SHELL32.DLL'
  136.  
  137. import kernel32, \
  138. ExitProcess,'ExitProcess', \
  139. GetCommandLine,'GetCommandLineA' ; ANSI-функция
  140. import user32, \
  141. MessageBox, 'MessageBoxA'
  142. import msvcrt, \
  143. sprintf, 'sprintf', \
  144. sscanf, 'sscanf', \
  145. strcmp, 'strcmp', \
  146. strcpy, 'strcpy'
  147. end data
Advertisement
Add Comment
Please, Sign In to add comment