Иллюстрированный самоучитель по задачам и примерам Assembler

Организация высокоуровневого консольного ввода-вывода

Ниже приведен пример пользовательского обработчика события – ввода комбинации CTRL + C или CTRL + Break. За основу взята предыдущая программа.

:prg05_12.asm – программа, демонстрирующая использование пользовательского обработчика события.
.data
Text_CTRL_C db "Нажаты CTRL + C"
Len_Text_CTRL=$-Text_CTRL_C
TextJREAK db "Нажаты CTRL + BREAK"
Len_BREAK=$-Text_BREAK
.code
CTRLHandler proc
arg @@dwCTRLType:DWORD
uses ebx.edi .esi;эти регистры обязательно должны сохраняться
:анализируем тип сигнала управления
cmp @@dwCTRLType.CTRL_C_EVENT
je h_CTRL_C_EVENT
cmp (a@dwCTRLType.CTRL_BREAK_EVENT
je h_CTRL_BREAK_EVENT
jmp h_default
h_CTRL_C_EVENT::при нажатии CTRL + C выводим сообщение: установим курсор
call SetConsoleCursorPosition:вывести строку Text_CTRL_C call WriteConsoleA
; возвращаем признак обработки
mov eax.l
jmp exit_CTRLHandler h_CTRL_BREAK_EVENT:
;при нажатии CTRL + BREAK выводим сообщение:
;установим курсор
call SetConsoleCursorPosition: вывести строку
call WriteConsoleA
;возвращаем признак обработки
mov eax.l
jmp exit_CTRLHandler
h_default: mov eax.Offffffffh;возвращаем остальное не обрабатываем
exit_CTRLHandler: ret CTRLHandler endp start proc near;точка входа в программу:
:работаем………
:получим стандартные дескрипторы ввода-вывода
;установим функцию-обработчик сигналов управления
push TRUE
push offset cs: CTRLHandler
call SetConsoleCTRLHandler
onp eax. 0
jz exit:если неуспех;введем строку в буфер TitleText установим курсор в позицию (2.6)
call SetConsoleCursorPosition call ReadConsoleA
:выведем введенную строку в заголовок окна консоли: push offset TitleText call SetConsoleTitleA
:выведем строку в окно консоли с различных позиций и с разными цветами
mov ecx.10:строку выведем 10 раз
mov bl.10000001b начальные атрибуты ml: push ecx установим курсор в позицию
call SetConsoleCursorPosition
;определим атрибуты выводимых символов – будем получать их циклически сдвигом регистра BL
 хоr еах.еах
rol b1.1
mov al,b1
push eax
push d0ut
call SetConsoleTextAttribute.:вывести строку TitleText
call WriteConsoleA cmp eax.0
jz exit;если неуспех pop ecx
loop ml

Относительно этой программы можно сделать два замечания. Первое касается функции HandlerRoutine, которая в нашей программе называется CTRL Handler. Как упоминалось, эта функция является функцией обратного вызова. Ее вызов производится при возникновении определенных событий неявно – из системы Windows. По структуре и алгоритму работы она аналогична оконной функции, которую мы рассматривали в уроке 18 "Создание Windows-приложений на ассемблере" учебника. Поэтому за всеми подробностями отсылаем читателя к этому материалу. Второе замечание касается порядка отладки приложений, содержащих определяемые пользователем функции (процедуры) обратного вызова.

Первое, что нужно сделать в процессе пошагового выполнения программы в отладчике, – выяснить адрес процедуры обратного вызова. В программе выше это можно сделать, выяснив, какое значение будет помещено в стек при выполнении команд:

……….
[установим функцию-обработчик сигналов управления
push TRUE
push offset cs: CTRL Handler
call SetConsoleCTRLHandler
cmp eax. 0
jz exit [если неуспех
………

После этого, сделав активным окно отладчика CPU (выбрав в меню команду View CPU), необходимо установить указатель мыши в окно с командами процессора и щелкнуть правой кнопкой мыши. В появившемся контекстном меню выберете пункт Goto…. В результате этих действий отладчик отобразит диалоговое окно, в которое необходимо внести адрес программы-обработчика CTRL Handler. В результате этого в верхней части окна команд отобразится первая команда процедуры CTRL Handler. Установите на нее курсор и нажмите клавишу F4.

Все, программа начнет выполняться по своему алгоритму. При нажатии пользователем управляющих комбинаций клавиш, допустимых функцией HandlerRoutine, управление будет передано этой функции, и вы сможете произвести ее отладку.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.