Быстрый поиск
Введите фрагмент названия статьи для поиска
Обработка подключения и отключения съемного накопителя
18.04.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
С расширением рынка переносных устройств и USB-накопителей становится актуальной задача по обработке их взаимодействия с компьютером. Сегодня разберем обработку подключения и отключения съемных накопителей, таких как Flash-диски, карты памяти и USB-диски. Начинаем с теории. При подключении или отключении съемного накопителя система посылает всем окнам (через глобальный хэндл HWND_BROADCAST) сообщение WM_DEVICECHANGE. Но это сообщение всего лишь о самом факте изменения состояния съемного накопителя, а более подробные значения содержатся в параметрах lParam и wParam этого сообщения. В wParam приходит расшифровка произошедшего события: подключение, отключение, изменения состояния, отмена отключения и т.п. Нас пока интересует только два: DBT_DEVICEARRIVAL - подключение сменного накопителя и DBT_DEVICEREMOVECOMPLETE - извлечение накопителя. Основной обработчик событий приложения ничем не отличается от обычных обработчиков. Нам также понадобятся несколько констант, которые по умолчанию не определены в FASM:Code (Assembler) : Убрать нумерацию
- DBT_DEVICEARRIVAL = 0x8000
- DBT_DEVICEREMOVECOMPLETE = 0x8004
- DBT_DEVTYP_VOLUME = 0x00000002
Code (Assembler) : Убрать нумерацию
- proc DialogProc hwnddlg,msg,wparam,lparam
- push ebx esi edi
- ...
- ; Пришло сообщение об изменении состояния съемного накопителя
- cmp [msg],WM_DEVICECHANGE
- je update_usb
- ...
- update_usb:
- ; Устройство подключено?
- cmp [wparam],DBT_DEVICEARRIVAL
- je usb_connected
- ; Устройство извлечено?
- cmp [wparam],DBT_DEVICEREMOVECOMPLETE
- je usb_disconnected
- jmp processed
- usb_connected:
- ; Обработка подключения устройства
- ...
- jmp processed
- usb_disconnected:
- ; Обработка отключения устройства
- ...
- jmp processed
- ...
- processed:
- mov eax,1
- finish:
- pop edi esi ebx
- ret
- endp
Читать статью целиком »
Просмотров: 7279 | Комментариев: 19
Splash-окно при загрузке программы
31.03.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
При запуске некоторых приложений иногда требуется выполнить какие-нибудь ресурсоемкие или продолжительные по времени действия, например, загрузка дополнительных модулей, сбор информации о системе, распаковка файлов данных и т.п. Часто во время таких процессов открывается так называемое splash-окно (его также называют "сплэш-окно" или сокращенно "сплэш"), то есть модальное окно без заголовка, расположенное по центру экрана, обычно с логотипом и названием программы. Также в нем меняющейся строкой отображается текущее действие программы, и, иногда, полоса прогресса выполнения. Таким образом пользователя как бы уведомляют, что программа не зависла при запуске, а просто выполняет нужные ей действия и надо немного подождать. После появления главного окна программы сплэш закрывается. Попробуем сделать что-нибудь подобное на Ассемблере.Сперва нарисуем само окно. Оно должно быть без заголовка, модальное, можно разместить на нем картинку-логотип. Для большего эффекта добавим на это окно прогрессбар и текстовое поле для отображения состояния загрузки.
Code (Assembler) : Убрать нумерацию
- ; Стиль прогрессбара - непрерывный бегунок. В FASM значение не определено,
- ; сделаем это самостоятельно
- PBS_MARQUEE = 8
- dialog demonstration,' Splash Demo',0, 0, 150, 60,\
- WS_POPUP+DS_CENTER+DS_SYSMODAL+WS_BORDER, WS_EX_TOOLWINDOW,0,'Arial',10
- dialogitem 'STATIC',1, 1, 0, 0, 138, 38 ,WS_VISIBLE+SS_BITMAP
- dialogitem 'STATIC','Loading...',ID_TEXT, 0, 34, 150, 8 ,WS_VISIBLE+SS_CENTER
- dialogitem 'msctls_progress32', '', IDC_PROGRESS, 3, 47, 145, 10,\
- WS_VISIBLE+PBS_MARQUEE
- dialogitem 'BUTTON','',IDCANCEL, 0, 0, 0, 0, 0
- enddialog
Читать статью целиком »
Просмотров: 7171 | Комментариев: 10
"FASM и UPX: созданы друг для друга"
25.03.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
Сразу скажу, утро и кофе к этой статье отношения не имеют, все необычные решения приходят ко мне обычно по ночам. Однажды я экспериментировал с FASM, и обнаружил один интересный момент. Ниже приведен ассемблерный листинг самой простейшей программы, она выводит на экран сообщение и сразу же завершает работу, вроде бы ничего необычного.Code (Assembler) : Убрать нумерацию
- section '.code' code readable executable
- start:
- ; Вывести окно сообщения и выйти из программы
- invoke MessageBox, NULL, szMess, szTitle, MB_OK
- invoke ExitProcess,0
- ; Куча пустого места, чтобы можно было упаковать файл
- rd 1000h
- szTitle db 'Title',0
- szMess db 'Hello, UPX ;)',0
- ;---------------------------------------------
- section '.idata' import data readable writeable
- ; Обратите внмание, user32.dll прописан дважды
- library kernel32,'kernel32.dll',\
- user32,'user32.dll',\
- user32,'user32.dll'
- include 'apia\kernel32.inc'
- include 'apia\user32.inc'
Читать статью целиком »
Просмотров: 6249 | Комментариев: 10
Управление лотком CD-ROM на Ассемблере
06.02.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
Открывать и закрывать лоток CD-ROM можно программными способами. Это может оказаться полезным в случаях, когда системный блок стоит в труднодоступном месте или по каким-либо иным причинам нет возможности управлять им при помощи механической кнопки. Также я читал истории, когда на лоток CD-ROM возлагались полезные функции, например, при выдвижении он замыкал контакты питания и отправлял сервер в перезагрузку, а администратор таким образом удаленно управлял им. Так что программное управление лотком CD-ROM имеет место быть, и наша задача научиться его делать. Чаще всего в разных интернетах описывается способ управления при помощи MCI (Media Control Interface). Кстати, именно этот способ приводится в качестве одного из примеров программ в пакете FASM.Code (Assembler) : Убрать нумерацию
- ...
- ; Открыть лоток CD-ROM
- invoke mciSendString,cmd_open,0,0,0
- invoke mciSendString,cmd_eject,0,0,0
- invoke mciSendString,cmd_close,0,0,0
- ...
- ; Закрыть лоток CD-ROM
- invoke mciSendString,cmd_open,0,0,0
- invoke mciSendString,cmd_load,0,0,0
- invoke mciSendString,cmd_close,0,0,0
- ...
- cmd_open db 'open cdaudio',0
- cmd_eject db 'set cdaudio door open',0
- cmd_load db 'set cdaudio door closed',0
- cmd_close db 'close cdaudio',0
Читать статью целиком »
Просмотров: 10246 | Комментариев: 6
Проверка баланса скобок на Ассемблере
28.01.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
Есть такая классическая задача по программированию: проверка правильности расстановки скобок в строке, или иначе проверка баланса скобок. Суть задачи заключается в том, что есть произвольное математическое выражение, записанное в строку, в этом выражении используется три вида скобок "( )", "[ ]" и "{ }", последовательность и вложенность может быть любая. Требуется проверить, все ли скобки закрыты, соответствует ли каждая закрывающая скобка открывающей и нет ли лишних закрывающих скобок. В разных интернетах есть решения на различных языках программирования, я решил добавить свое решение на Ассемблере, тем более, что он идеально подходит для реализации этого алгоритма.Решение заключается в том, что мы двигаемся по строке с самого начала, перебирая все символы по одному. Если символ является открывающей скобкой любого типа, то мы помещаем его в стек. Если символ является закрывающей скобкой, то берем из стека последнюю сохраненную открывающую скобку и проверяем на соответствие. Если не совпадают - ошибка несоответствия скобок, если стек пустой, то ошибка лишней закрывающей скобки. Если конец строки достигнут, но стек не пустой, то ошибка незакрытых скобок. Как видите, решение целиком построено на работе со стеком, а Ассемблер предоставляет для этого все возможности. Переходим к программированию.
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------------------------------
- ; Функция проверки правильности расстановки скобок в выражении
- ; На входе: указатель на строку ASCIIZ
- ; На выходе: EAX - результат проверки выражения
- ; 0 - скобки расставлены правильно
- ; 1 - ОШИБКА: скобки не совпадают
- ; 2 - ОШИБКА: закрывающая скобка без открывающей
- ; 3 - ОШИБКА: открывающая скобка без закрывающей
- ;------------------------------------------------------------------------
- proc CheckBrackets str:DWORD
- local res:DWORD ; Результат
- pusha ; Сохранить все регистры
- mov esi,[str] ; Указатель на строку
- cld
- xor ecx,ecx ; Глубина стека
- mov [res],0 ; Результат проверки
- .scan_expr:
- lodsb ; Прочитать символ из строки
- or al,al ; Конец строки достигнут?
- jz .finish
- ; Проверить открывающие скобки
- cmp al,'['
- je .push_bracket
- cmp al,'('
- je .push_bracket
- cmp al,'{'
- je .push_bracket
- ; Проверить закрывающие скобки
- cmp al,']'
- je .pop_bracket
- cmp al,')'
- je .pop_bracket
- cmp al,'}'
- je .pop_bracket
- jmp .scan_expr ; Следующий символ
- ; Занести скобку в стек
- .push_bracket:
- inc ecx ; Увеличить счетчик
- movzx eax,al ; Записать скобку в стек
- push eax
- jmp .scan_expr ; Следующий символ
- ; Извлечь скобку из стека
- .pop_bracket:
- or ecx,ecx ; В стеке ничего нет?
- jne @f
- ; ОШИБКА: закрывающая скобка без открывающей
- mov [res],2
- jmp .finish
- @@:
- dec ecx ; Уменьшить счетчик
- pop ebx ; Извлечь из стека скобку
- ; Проверить закрывающие скобки
- cmp bl,'['
- jne @f
- cmp al,']' ; Скобки совпадают?
- je .scan_expr ; Да, следующий символ
- @@:
- cmp bl,'('
- jne @f
- cmp al,')' ; Скобки совпадают?
- je .scan_expr ; Да, следующий символ
- @@:
- cmp bl,'{'
- jne @f
- cmp al,'}' ; Скобки совпадают?
- je .scan_expr ; Да, следующий символ
- @@:
- ; ОШИБКА: скобки не совпадают
- mov [res],1
- or ecx,ecx ; В стеке пусто?
- jz .exit ; Да, просто на выход
- jmp .clean_stack ; Надо почистить стек
- .finish:
- or ecx,ecx ; Все проверили и в стеке пусто?
- jz .exit ; Да, скобки расставлены правильно
- ; ОШИБКА: открывающая скобка без закрывающей
- mov [res],3
- ; Почистить стек от оставшихся скобок
- .clean_stack:
- pop eax
- loop .clean_stack
- .exit:
- popa ; Восстановить все регистры
- mov eax,[res]
- ret
- endp
Читать статью целиком »
Просмотров: 7299 | Комментариев: 4