Code .586 .MODEL flat, stdcall OPTION CASEMAP:NONE
Include windows.inc Include kernel32.inc include user32.inc Include masm32.inc
IncludeLib kernel32.lib includelib user32.lib IncludeLib masm32.lib
;Следующие прототипы и макросы можно прописать в собственном INC файле (если хотите) Main PROTO GetStrLen PROTO :PTR Main PROTO ReverseText PROTO :PTR, :PTR Ucase PROTO :PTR
Print_Ru_Text Macro txt:REQ invoke CharToOem, addr txt, addr inbuf2 Invoke StdOut, ADDR inbuf2 EndM
Print_Text Macro txt:REQ Invoke StdOut, ADDR txt EndM
Get_Input Macro prompt:REQ, buffer:REQ invoke CharToOem, addr prompt, addr inbuf2 Invoke StdOut,ADDR inbuf2 Invoke StdIn,ADDR buffer, LengthOf buffer EndM
.CONST
.DATA Msg1 DB "Ввод: ",0 Msg2 DB "Вы ввели: ",0 Msg3 DB "Развёрнутый текст:",0 Msg4 DB "Жми Enter для выхода",0 CRLF DB 0AH,0DH,0
.DATA? inbuf DB 100 DUP (?) inbuf2 DB 100 DUP (?) textbuf2 DB 100 DUP (?)
.CODE Start: Invoke Main Invoke ExitProcess,0
Main Proc XOR EAX,EAX Get_Input Msg1, inbuf Invoke ReverseText,Offset inbuf,Offset textbuf2 Invoke Ucase,Offset textbuf2 Print_Ru_Text Msg2 Print_Text inbuf Print_Ru_Text Msg3 Print_Text textbuf2 Print_Text CRLF Get_Input Msg4,inbuf RET Main EndP
; Переворачиваем строку ReverseText Proc Uses EBX,_src:PTR,_dst:PTR Invoke GetStrLen,_src ; Помещаем длину строки в EAX MOV ECX,_src ; Переносим указатель на строку источник в ECX MOV EDX,_dst ; Переносим указатель на строку приёмник в EDX MOV BYTE PTR[EDX+EAX],NULL ; Устанавливаем ноль в конце строки, т.к. это не Unicode next_char: MOV BL,BYTE PTR[ECX+EAX-1] ; Копируем последний BYTE строки источника в BL MOV [EDX],BL ; Копируем из BL в первый BYTE строки приёмника INC EDX ; Увиличиваем указатель приёмника DEC EAX ; Уменьшаем указатель источника JG next_char ; Если EAX == 0 то выходим RET ReverseText EndP
;Конвертирует строку в верхний регистр Ucase Proc,_str:PTR Invoke GetStrLen,_str MOV ECX,_str next_char: CMP BYTE PTR[ECX+EAX-1],"a" ; Сравниваем BYTE сначение с ascii "a"(61H) JB inc_char CMP BYTE PTR[ECX+EAX-1],"z" ; Сравниваем BYTE значение с ascii "z"(7AH) JA inc_char ADD BYTE PTR[ECX+EAX-1],"A"-"a" ; 61H <= BYTE значение <= 7AH inc_char: DEC EAX JG next_char ; если счётчик >=0 переходим к следующему символу RET Ucase EndP
; Возвращаем длину строки (не включая NULL терминатор (завершающий 0)) GetStrLen Proc ,_str:PTR MOV ECX,_str MOV EAX,-1 next_char: INC EAX ; EAX==NULL CMP BYTE PTR[ECX+EAX],NULL JNE next_char ; Если BYTE не равен NULL продолжаем . RET ; Возвращаем длину в EAX GetStrLen EndP
End Start Макрос от процедуры (функции) можно отличить по словам Macro и Proc. В этом примере можно увидеть как передаются параметры через регистры, как пользоваться указателями на данные, как можно написать свой макрос и процедуру. За вывод и ввод символов кириллицы отвечает два макроса, это: Print_Ru_Text и Get_Input. Если будут вопросы пишите в коментариях, я, или дополню статью, или отвечу там же.
|