Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; Фомин Сергей, БПИ182-2
- ; Разработать программу, вычисляющую число букв латиницы и кириллицы в заданной ASCII-строке
- format PE GUI 4.0 ; GUI-приложение для Windows (EXE-файл)
- include "c:/emu8086/fasm/include/win32ax.inc" ; путь к подкаталогу /include/
- .code ; начало секции кода
- start: ; точка старта программы
- cinvoke GetCommandLine ; взяли командную строку
- mov [lpCommLine], eax ; запомнили указатель на командную строку в eax
- cinvoke sscanf, [lpCommLine], input_str, s1 ; из строки по формату читается s1, args[0] игнорируется
- ; Проверка входной строки на вызов справки
- cinvoke strcmp, s1, "-h"
- cmp al, 0
- jnz not_h
- cinvoke MessageBox, 0, help_str, "Число букв латиницы и кириллицы", MB_OK
- cinvoke ExitProcess, 0
- not_h:
- cinvoke strcmp, s1, "-?"
- cmp al, 0
- jnz not_question
- cinvoke MessageBox, 0, help_str, "Число букв латиницы и кириллицы", MB_OK
- cinvoke ExitProcess, 0
- not_question:
- ; Если входная строка пустая, то посчитаем символы для sample_str (занесём её в s1)
- cinvoke strcmp, s1, ""
- cmp al, 0
- jnz check_string
- cinvoke strcpy, s1, sample_str
- check_string:
- push s1 ; записываем в стек нашу строку
- call strcntcyrillic ; вызываем strcntcyrillic для строки s1
- add esp, 4 ; восстановим стек после strcntcyrillic
- mov [latcnt], eax ; в eax хранится количество латинских букв
- mov [cyrcnt], ebx ; в ebx хранится количество букв кириллицы
- cinvoke sprintf, res_str, form_str, s1, [latcnt], [cyrcnt] ; формируем строчку для вывода
- cinvoke MessageBox, 0, res_str, "Число букв латиницы и кириллицы", MB_OK ; выводим готовую строчку
- cinvoke ExitProcess,0 ; выход из программы с кодом возврата 0
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- proc strcntcyrillic ; принимает со стека s1(стек не корректируется - соглашение cdecl)
- ; задействованы регистры eax, ebx, ecx, edx, esi
- ; на выходе в регистре eax хранится количество латинских букв, в ebx - букв кириллицы
- mov esi, [esp+4] ; в esi запоминаем начало обрабатываемой строки
- mov ecx, 0d ; ecx будет хранить количество латинских букв
- mov edx, 0d ; edx хранит количество букв кириллицы
- mov esi, [esp+4] ; esi <- edi (начало сканирования строки)
- retry: ; начало проверки очередного символа
- mov al, [esi] ; копируем текущий символ в al для проверки, каким символом он является
- ; если код символа лежит в пределах от 'A' (латиница) до 'Z' (латиница), то увеличиваем ecx (латиница)
- cmp al, 'A'
- jl not_add_big_lat
- cmp al, 'Z'
- jg not_add_big_lat
- inc ecx
- not_add_big_lat:
- ; если код символа лежит в пределах от 'a' (латиница) до 'z' (латиница), то увеличиваем ecx (латиница)
- cmp al, 'a'
- jl not_add_small_lat
- cmp al, 'z'
- jg not_add_small_lat
- inc ecx
- not_add_small_lat:
- ; если код символа лежит в пределах от 'А' (кириллица) до 'п' (кириллица), то увеличиваем ecx (латиница)
- cmp al, 'А'
- jl not_add_cyr_1
- cmp al, 'п'
- jg not_add_cyr_1
- inc edx
- not_add_cyr_1:
- ; если код символа лежит в пределах от 'р' (кириллица) до 'я' (кириллица), то увеличиваем ecx (кириллица)
- cmp al, 'р'
- jl not_add_cyr_2
- cmp al, 'я'
- jg not_add_cyr_2
- inc edx
- not_add_cyr_2:
- ; из-за разных кодировок 'ё', 'Ё' надо обрабатывать отдел
- ; проверка на 'ё'
- cmp al, 'ё'
- jnz not_add_small_yo
- inc edx
- not_add_small_yo:
- ; проверка на 'Ё'
- cmp al, 'Ё'
- jnz not_add_big_yo
- inc edx
- not_add_big_yo:
- cmp al, 0 ; проверка на нуль-терминатор
- jz str_end ; если 0, то выходим из цикла
- inc esi ; перемещаемся на следующий символ
- jmp retry ; переход в начало проверки следующего символа
- str_end: ; по окончании цикла в ecx хранится количество латинских букв, в edx - кириллицы
- mov eax, ecx ; для красоты перенесём результат в более привычные регистры
- mov ebx, edx ; eax - количество латинских букв, ebx - кириллицы
- ret
- endp ; конец процедуры
- .data ; секция данных
- lpCommLine dd ? ; указатель на командную строку
- s1 db 4096 dup(?) ; обрабатываемая ASCII-строка (символ=байт)
- res_str db 4096 dup(?) ; строка для хранения готового отформатированного вывода
- form_str db "Исходная строка: ""%s""",10, 10, "Букв латиницы: %d", 10, "Букв кириллицы: %d", 10, 0 ; строка формата вывода
- input_str db "%*s %[^", 0, "]", 10, 0 ; Входная строчка (первый аргумента (расположение) игнорируется, второй - считывание всех символов до конца строки)
- help_str db "Данная программа принимает в качестве аргумента строчку и считает в ней количество букв кириллицы и количество букв латиницы.", 10, 0
- sample_str db "Съешь ещё этих мягких французских булок, да выпей же чаю. The quick brown fox jumps over the lazy dog.", 0 ; строка для примера
- latcnt dd 0 ; количество латинских букв
- cyrcnt dd 0 ; количество букв кириллицы
- data import ; импортируем стандартные функции Windows
- library user32,'USER32.DLL', \
- msvcrt,'MSVCRT.DLL', \
- kernel32,'KERNEL32.DLL', \
- shell32,'SHELL32.DLL'
- import kernel32, \
- ExitProcess,'ExitProcess', \
- GetCommandLine,'GetCommandLineA' ; ANSI-функция
- import user32, \
- MessageBox, 'MessageBoxA'
- import msvcrt, \
- sprintf, 'sprintf', \
- sscanf, 'sscanf', \
- strcmp, 'strcmp', \
- strcpy, 'strcpy'
- end data
Advertisement
Add Comment
Please, Sign In to add comment