Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Консольные приложения WindowsСодержание книги
Поиск на нашем сайте Консольные приложения представляют собой систему средств взаимодействия пользователя с компьютером, основанную на использовании текстового (буквенно-цифрового) режима дисплея или аналогичных (командная строка MS-DOS, Far). Консольные приложения очень компактны не только в откомпилированном виде, но и в текстовом варианте, и имеют такие же возможности обращаться к ресурсам Windows посредством API-функций, как и обычные графические приложение. Для работы с консольными приложениями Windows используются соответствующие функции Windows API. В программе на ассемблере записываются имена вызываемых функций как внешние, а сами функции расположены в системном каталоге Windows. Для обращения к ним используется подключаемый файл библиотеки (*.lib), в котором указывается, в каком системном.dll файле расположена вызываемая функция и файл описания прототипов функций (*.inc). Для подключения файла библиотеки используется директива includelib, для подключения файла прототипа – директива include: include С:\masm32\include\kernel32.inc includelib С:\masm32\lib\kernel32.lib Подключаемые библиотеки могут указываться в программе при помощи директивы includelib или при сборке приложения (команда link). Пример простейшего консольного приложения. .586 .MODEL flat, stdcall STD_OUTPUT_HANDLE EQU -11 ; константа Win API
include C:\masm32\include\kernel32.inc include C:\masm32\include\user32.inc include C:\masm32\include\msvcrt.inc includelib C:\masm32\lib\msvcrt.lib .data consoleOutHandle dd? ; дескриптор консоли вывода bytesWritten dd? ; количество байт(вспомогательная) message db "Привет всем!",13,10,0; текст (13 = \r, 10=\n 0=\0) h EQU $-message; ; длина текстовой строки (константа)
.code main PROC ; начало функции INVOKE GetStdHandle, STD_OUTPUT_HANDLE; Получить дескриптор консоли ввода mov consoleOutHandle,eax ; поместить его в EAX
INVOKE CharToOem,offset message,offset message; перекодировка сообщения
mov eax, h INVOKE WriteConsole, ; функция вывода в консоль consoleOutHandle, ; дескриптор консоли offset message, ; указатель строки eax, ; длина строки offset bytesWritten, ; количество выведенных байт 0 ; возвращается функцией
INVOKE crt__getch INVOKE ExitProcess,0 ; Окончание программы main ENDP ; окончание процедуры (функции) END main ; окончание модуля Функция получения дескриптора стандартного устройства ввода, вывода или ошибки в зависимости от переданного константного параметра: HANDLE WINAPI GetStdHandle(__in DWORD nStdHandle); nStdHandle может принимать значения STD_INPUT_HANDLE = -10 устройство ввода STD_OUTPUT_HANDLE = -11 устройство вывода STD_ERROR_HANDLE = -12 ошибка Функция перекодировки русского текста, введенного в Win-кодовой странице, в код, читаемый в консоли (DOS-кодировку). Возвращаемое значение 1 в случае успешной перекодировки. BOOL CharToOem(LPCTSTR lpszSrc, LPSTR lpszDst) lpszSrc – указатель на строку-источник; lpszDst – указатель на строку-приемник; Функция вывода текстовой информации в консоль. BOOL WINAPI WriteConsole( __in HANDLE hConsoleOutput, __in const VOID* lpBuffer, __in DWORD nNumberOfCharsToWrite, __out LPDWORD lpNumberOfCharsWritten, __reserved LPVOID lpReserved); hConsoleOutput – дескриптор буфера вывода консоли, который может быть получен при помощи функции GetStdHandle. lpBuffer – указатель на буфер, где находится выводимый текст. nNumberOfCharsToWrite – количество выводимых символов. lpNumberOfCharsWritten – указывает на переменную DD, куда будет помещено количество действительно выведенных символов. lpReserved – резервный параметр, должен быть равен 0. Буфер, где находится выводимый текст, не обязательно должен заканчиваться нулем, поскольку для данной функции указывается количество выводимых символов. Функция завершения Windows-приложения. VOID WINAPI ExitProcess(__in UINT uExitCode); параметр uExitCode – код завершения. Для трансляции консольного приложения из командной строки используются следующие команды ml /с /coff cons1.asm link /subsystem:console cons1.obj При этом необходимо объявить все вызываемые API-функции как внешние с помощью директивы EXTERN. Трансляция из Visual Studio осуществляется аналогично диалоговому приложению, но необходимо указать платформу subsystem:console либо при создании проекта (тип Win32 Console Application), либо указать в уже существующем проекте в окне свойств. Основные динамические библиотеки kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib подключаются в командной строке редактора связей link.exe в Visual Studio, поэтому отсутствие директив типа includelib С:\masm32\lib\kernel32.lib не будет ошибкой.
Библиотеки kernel32.lib, user32.lib подключаются линковщиком по умолчанию, поэтому нет необходимости подключать их директивой includelib. Консольные приложения могут создать свою консоль. В этом случае весь ввод-вывод будет производиться в эту консоль. Если приложение консоль не создает, то здесь может возникнуть двоякая ситуация: либо наследуется консоль, в которой программа была запущена (например, консоль Fara), либо Windows создает для приложения свою консоль. Для того чтобы создать свою консоль, используется функция BOOL WINAPI AllocConsole(void); По завершении программы все выделенные консоли автоматически освобождаются. Однако это можно сделать и принудительно, используя функцию BOOL WINAPI FreeConsole(void);
Дополнительные функции для работы с консолью
Функция чтения строки из буфера консоли BOOL WINAPI ReadConsole( __in HANDLE hConsoleInput, __out LPVOID lpBuffer, __in DWORD nNumberOfCharsToRead, __out LPDWORD lpNumberOfCharsRead, __in_opt LPVOID pInputControl); hConsoleInput – дексриптор буфера ввода консоли, полученного функцией GetStdHandle. lpBuffer – указатель на буфер, куда помещается вводимый текст. nNumberOfCharsToRead – длина буфера ввода. lpNumberOfCharsRead– указатель на переменную DD (32 бит), куда будет помещено количество действительно введенных символов. pInputControl – резервный параметр, должен быть равен нулю. Функция опредления размеров окна консоли BOOL WINAPI SetConsoleScreenBufferSize( __in HANDLE hConsoleOutput, __in COORD dwSize); hConsoleOutput – дексриптор буфера вывода консоли; dwSize – структура координат, задающая размер окна консоли: COORD STRUC X DW? Y DW? COORD ENDS Функция установки позиции курсора в окне консоли BOOL WINAPI SetConsoleCursorPosition( __in HANDLE hConsoleOutput, __in COORD dwCursorPosition); hConsoleOutput– дексриптор буфера выходной консоли; dwCursorPosition– структура координат COORD, определяющая позицию курсора. Функция определения заголовка окна консоли BOOL WINAPI SetConsoleTitle(__in LPCTSTR lpConsoleTitle); lpConsoleTitle — указатель на строку имени консоли, заканчивающуюся нуль-символом. Функция определения атрибутов вводимых символов в окне консоли BOOL WINAPI SetConsoleTextAttribute( __in HANDLE hConsoleOutput, __in WORD wAttributes); hConsoleOutput – дексриптор буфера вывода консоли; wAttributes – цвет букв и фона, получаемый путем комбинации констант FOREGROUND_BLUE equ 1h;синий FOREGROUND_GREEN equ 2h;зеленый FOREGROUND_RED equ 4h;красный FOREGROUND_INTENSITY equ 8h;интенсивный BACKGROUND_BLUE equ 10h;синий фон букв BACKGROUND_GREEN equ 20h;зеленый фон букв BACKGROUND_RED equ 40h;красный фон букв BACKGROUND_INTENSITY equ 80h;интенсивный фон букв Функция, задающая цвет фона консоли (путем закрашивания фона отдельных символов) BOOL WINAPI FillConsoleOutputAttribute( __in HANDLE hConsoleOutput, __in WORD wAttribute, __in DWORD nLength, __in COORD dwWriteCoord, __out LPDWORD lpNumberOfAttrsWritten); hConsoleOutput – дексриптор буфера вывода консоли; wAttribute – атрибут цвета фона символа в консоли; nLength – количество ячеек символов, фон которых устанавливается заданным цветом; dwWriteCoord – координаты первой закрашиваемой ячейки; lpNumberOfAttrsWritten – указатель на 4-байтный идентификатор, в который записывается количество реально закрашенных ячеек. Функция, получающая информацию о клавиатуре и мыши в консольном режиме: BOOL WINAPI ReadConsoleInput( __in HANDLE hConsoleInput, __out PINPUT_RECORD lpBuffer, __in DWORD nLength, __out LPDWORD lpNumberOfEventsRead); hConsoleInput – дескриптор входного буфера консоли; lpBuffer – указатель на структуру (или массив структур) PINPUT_RECORD, в которой содержится информация о событиях, происшедших с консолью; nLength – количество получаемых информационных записей (структур); lpNumberOfEventsRead – указатель на двойное слово, содержащее количество реально полученных записей. Структура PINPUT_RECORD используется для получения события, происшедшего в консоли. Всего системой зарезервировано пять типов событий: KEY_EV equ 1h ; клавиатурное событие MOUSE_EV equ 2h ; событие с мышью WINDOW_BUFFER_SIZE_EV equ 4h ; изменился размер окна MENU_EV equ 8h ; зарезервировано FOCUS_EV equ 10h ; зарезервировано Остальные байты структуры зависят от происшедшего события. Событие KEY_EVENT KEY_EVENT_RECORD STRUCT bKeyDown DD?;При нажатии клавиши значение поля больше нуля wRepeatCount DW?;Количество повторов при удержании клавиши wVirtualKeyCode DW?;Виртуальный код клавиши wVirtualScanCode DW?;Скан-код клавиши UNION UnicodeChar DW?;код символа в формате Unicode ;для функции (ReadConsoleInputW) AsciiChar DB?;код символа в формате ASCII ENDS ;для функции (ReadConsoleInputA) dwControlKeyState DD?;Содержится состояния управляющих клавиш. ;Может являться суммой следующих констант: ; RIGHT_ALT_PRESSED equ 1h ; LEFT_ALT_PRESSED equ 2h ; RIGHT_CTRL_PRESSED equ 4h ; LEFT_CTRL_PRESSED equ 8h ; SHIFT_PRESSED equ 10h ; NUMLOCK_ON equ 20h ; SCROLLLOCK_ON equ 40h ; CAPSLOCK_ON equ 80h ; ENHANCED_KEY equ 100h KEY_EVENT_RECORD ENDS Событие MOUSE_EVENT MOUSE_EVENT_RECORD STRUCT dwMousePosition COORD <>;координаты курсора мыши dwButtonState DD? ; состояние кнопок мыши. ;первый бит - левая кнопка, ;второй бит - правая кнопка, ;третий бит - средняя кнопка. ;Бит установлен - кнопка нажата. dwControlKeyState DD? ; Состояние управляющих клавиш dwEventFlags DD? ; Может содержать значения: ; MOUSE_MOVED equ 1h; было движение мыши ; DOUBLE_CLICK equ 2h; был двойной щелчок MOUSE_EVENT_RECORD ENDS
Событие WINDOW_BUFFER_SIZE_EVENT WINDOW_BUFFER_SIZE_RECORD STRUCT dwSize COORD <>; новый размер консольного окна WINDOW_BUFFER_SIZE_RECORD ENDS
События MENU_EVENT_RECORD и FOCUS_EVENT_RECORD зарезервированы. MENU_EVENT_RECORD STRUCT dwCommandId DD? MENU_EVENT_RECORD ENDS
FOCUS_EVENT_RECORD STRUCT bSetFocus DD? FOCUS_EVENT_RECORD ENDS
Структура, объединяющая все типы событий: INPUT_RECORD STRUCT EventType DW? DW? MY UNION KeyEvent KEY_EVENT_RECORD <> MouseEvent MOUSE_EVENT_RECORD <> WindowBufferSizeEvent WINDOW_BUFFER_SIZE_RECORD <> MenuEvent MENU_EVENT_RECORD <> FocusEvent FOCUS_EVENT_RECORD <> MY ENDS INPUT_RECORD ENDS В данном случае структуры всех событий: KeyEvent, MouseEvent, WindowBufferSizeEvent, MenuEvent, FocusEvent будут находиться в одной и той же области памяти размером 16 байт (по максимальной длине структуры KeyEvent, MouseEvent). Рассмотрим пример консольного приложения: посчитать количество символов в строке. Программа состоит из двух файлов. Файл console.inc содержит основные конструкции и константы Windows, необходимые при написании программы, а также основные функции. Файл mmm.asm содержит текст программы. ; файл console.inc include c:\masm32\include\user32.inc include c:\masm32\include\kernel32.inc
; константы дескрипторов буфера STD_INPUT_HANDLE equ -10 STD_OUTPUT_HANDLE equ -11 STD_ERROR_HANDLE equ -12
; структура координат COORD STRUC X DW? Y DW? COORD ENDS
;Цвет окна консоли FOREGROUND_BLUE equ 1h; синий цвет букв FOREGROUND_GREEN equ 2h; зеленый цвет букв FOREGROUND_RED equ 4h; красный цвет букв FOREGROUND_INTENSITY equ 8h; повышенная интенсивность BACKGROUND_BLUE equ 10h; синий свет фона BACKGROUND_GREEN equ 20h; зеленый цвет фона BACKGROUND_RED equ 40h; красный цвет фона BACKGROUND_INTENSITY equ 80h; повышенная интенсивность
; тип события KEY_EV equ 1h ; клавиатурное событие MOUSE_EV equ 2h ; событие с мышью WINDOW_BUFFER_SIZE_EV equ 4h ; изменился размер окна MENU_EV equ 8h ; зарезервировано FOCUS_EV equ 10h ; зарезервировано
; константы - состояния клавиатуры RIGHT_ALT_PRESSED equ 1h LEFT_ALT_PRESSED equ 2h RIGHT_CTRL_PRESSED equ 4h LEFT_CTRL_PRESSED equ 8h SHIFT_PRESSED equ 10h NUMLOCK_ON equ 20h SCROLLLOCK_ON equ 40h CAPSLOCK_ON equ 80h ENHANCED_KEY equ 100h
;события мыши MOUSE_MOVED equ 1h; было движение мыши DOUBLE_CLICK equ 2h; был двойной щелчок
;описание событий структуры PINPUT_RECORD ;событие мыши MOUSE_EVENT_RECORD STRUCT dwMousePosition COORD <> dwButtonState DWORD? dwControlKeyState DWORD? dwEventFlags DWORD? MOUSE_EVENT_RECORD ENDS
;событие клавиатуры KEY_EVENT_RECORD STRUCT bKeyDown DD? wRepeatCount DW? wVirtualKeyCode DW? wVirtualScanCode DW? UNION UnicodeChar DW? AsciiChar DB? ENDS dwControlKeyState DD? KEY_EVENT_RECORD ENDS
;изменение размера окна консоли WINDOW_BUFFER_SIZE_RECORD STRUCT dwSize COORD <> WINDOW_BUFFER_SIZE_RECORD ENDS
MENU_EVENT_RECORD STRUCT dwCommandId DWORD? MENU_EVENT_RECORD ENDS
FOCUS_EVENT_RECORD STRUCT bSetFocus DWORD? FOCUS_EVENT_RECORD ENDS
;Структура PINPUT_RECORD INPUT_RECORD STRUCT EventType DW? DW? UNION KeyEvent KEY_EVENT_RECORD <> MouseEvent MOUSE_EVENT_RECORD <> WindowBufferSizeEvent WINDOW_BUFFER_SIZE_RECORD <> MenuEvent MENU_EVENT_RECORD <> FocusEvent FOCUS_EVENT_RECORD <> ENDS INPUT_RECORD ENDS
; Секция данных содержит временные переменные .data @CO DD? @numBytes DD? KeyEvent INPUT_RECORD <> @SYMBOL DB? .code ;------------------------------------------------------------------- ; Функция считывание символа в консоли ; consoleInHandle - дескриптор буфера консоли ввода ; consoleOutHandle - дескриптор буфера консоли вывода ; Display - управление отображением символа: ; 0 - символ отображается ; 1 - символ не отображается ; функция возвращает считанный символ в регистре al ReadSymbol proc consoleInHandle:DWORD, consoleOutHandle:DWORD, Display:DWORD @L1: INVOKE ReadConsoleInputA, consoleInHandle, offset KeyEvent, 1, offset @CO CMP KeyEvent.EventType,KEY_EV JNE @L1
; сохранение введенного символа MOV AL, KeyEvent.KeyEvent.AsciiChar MOV @SYMBOL, AL
CMP Display,0 JNE @L2
;вывод символа INVOKE WriteConsoleA, consoleOutHandle, OFFSET @SYMBOL, 1, OFFSET @numBytes, 0 ; Считывание события клавиатуры отпускания клавиши @L2: INVOKE ReadConsoleInputA, consoleInHandle, offset KeyEvent, 1, offset @CO CMP KeyEvent.EventType,KEY_EV JNE @L2
mov eax,0 mov al, @SYMBOL ret ReadSymbol endp ;------------------------------------------------------------------- ;Представление целого числа в текстовой форме ; Number - целое число ; Str1 - указатель на строку, в которую будет помещено представление числа ; функция возвращает длину строки символов в регистре EAX IntToStr proc Number:DWORD, Str1:DWORD MOV EAX, Number MOV EDI,Str1 MOV ECX, 0 CMP EAX,0 JGE @I1 MOV DL, '-' MOV [EDI],DL INC EDI NOT EAX INC EAX @I1: MOV EBX, 10 MOV EDX, 0 IDIV EBX PUSH EDX INC ECX CMP EAX,0 JG @I1 ; MOV EBX,ECX @I2: POP EDX ADD DL, 30h MOV [EDI],DL INC EDI LOOP @I2 MOV DL,0 MOV [EDI], DL INC EDI MOV EAX, EDI SUB EAX, Str1 ret IntToStr endp ;------------------------------------------------------------------- ;Определение длины строки ;Str1 - указатель на строку ; функция возвращает длину строки символов в регистре EAX LENSTR PROC Str1:DWORD CLD CLD MOV EDI, Str1 MOV EBX,EDI MOV ECX,100; ограничить длину строки MOV EAX, 0 REPNE SCASB; найти символ 0 SUB EDI, EBX; длина строки, включая 0 MOV EAX,EDI DEC EAX RET LENSTR ENDP ;------------------------------------------------------------------- ; Вывод строки в окно консоли ; StrPtr - указатель на выводимую строку, оканчивающуюся 0 ; consoleOutHandle - дескриптор буфера консоли вывода PrintStr proc StrPtr:DWORD, Handle:DWORD INVOKE CharToOem, StrPtr, StrPtr INVOKE LENSTR, StrPtr; определение длины строки INVOKE WriteConsole, Handle, StrPtr, eax, OFFSET @numBytes, 0 ret PrintStr endp
; файл mmm.asm .586 .MODEL FLAT, stdcall include console.inc .DATA consoleOutHandle DD?; дескриптор выходного буфера consoleInHandle DD?; дескриптор входного буфера COUNT DD 0 ; счетчик количество символов numBytes DD? TITL DB "Подсчет количества символов в строке",0 IN_STR DB "Введите строку: ",0 IN_SYM DB "Введите символ: ",0 BUF DB 200 dup (?); для ввода строки Len DD? ; длина введенной строки Yes DB 13,10,"Количество символов: ",0 No DB 13,10,"Символ не найден.",0 SymCount DB 10 dup(?); строка с количеством символов CRD COORD <?> ; структура координат .CODE START proc ; образовать консоль, вначале освободить уже существующую INVOKE FreeConsole INVOKE AllocConsole ; получить дескрипторы INVOKE GetStdHandle, STD_INPUT_HANDLE MOV consoleInHandle,EAX INVOKE GetStdHandle, STD_OUTPUT_HANDLE MOV consoleOutHandle,EAX ; задать заголовок окна консоли INVOKE CharToOem, OFFSET TITL, OFFSET TITL INVOKE SetConsoleTitle, OFFSET TITL ; задать размер окна консоли MOV CRD.X, 80 MOV CRD.Y, 25 mov eax, CRD INVOKE SetConsoleScreenBufferSize, consoleOutHandle, EAX ; задать цвет окна консоли INVOKE FillConsoleOutputAttribute, consoleOutHandle, BACKGROUND_BLUE + BACKGROUND_GREEN, 2000, 0, offset numBytes ; установить позицию курсора MOV CRD.X,0 MOV CRD.Y,2 mov eax, CRD INVOKE SetConsoleCursorPosition, consoleOutHandle, EAX ; задать цветовые атрибуты выводимого текста INVOKE SetConsoleTextAttribute, consoleOutHandle, FOREGROUND_BLUE + \ BACKGROUND_BLUE + BACKGROUND_GREEN
;Вывод сообщения Введите строку: INVOKE PrintStr, offset IN_STR, consoleOutHandle ;Ввод строки INVOKE ReadConsole, consoleInHandle, OFFSET BUF, 200, OFFSET numBytes, 0 ; Сохранить длину введенной строки MOV EAX, numBytes MOV Len, EAX ;Вывод сообщения Введите символ: INVOKE PrintStr, offset IN_SYM, consoleOutHandle ;Считывание символа INVOKE ReadSymbol, consoleInHandle, consoleOutHandle, 0 ; поиск символа в строке ; символ содержится в регистре AL CLD ; поиск символа с начала строки DF=0 LEA EDI, BUF; MOV ECX, Len;количество повторений равно длине строки FIND: repne SCASB JNE FAILED; просмотр строки завершен INC COUNT JMP FIND ; символ не найден FAILED: CMP COUNT, 0 JNE FOUND; количество символов не 0 – идем на FOUND INVOKE CharToOem, OFFSET No, OFFSET No; таких символов нет INVOKE PrintStr, offset No, consoleOutHandle JMP EXIT ; символ найден FOUND: INVOKE PrintStr, offset Yes, consoleOutHandle INVOKE IntToStr, COUNT, offset SymCount INVOKE PrintStr, offset SymCount, consoleOutHandle EXIT: INVOKE ReadSymbol, consoleInHandle, consoleOutHandle, 1 INVOKE ExitProcess,0 RET START ENDP END START
|
||
|
Последнее изменение этой страницы: 2020-12-09; просмотров: 453; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.217.21 (0.009 с.) |