Быстрый поиск
Введите фрагмент названия статьи для поиска
Разбор параметров командной строки
03.03.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Наконец-то добрался до полезной практической задачи по корректному разбору параметров командной строки. На языках высокого уровня это делается чуть ли не одной командой, а на Ассемблере как обычно приходится все делать самостоятельно. Решение получилось универсальным, подходит как для консольных, так и для GUI-приложений. Для использования функции ParseCmdLine в сегменте данных надо предварительно определить следующую структуру:Code (Assembler) : Убрать нумерацию
- ; Структура для командной строки
- struct CMDLINE
- nCount dd ? ; Количество аргументов
- lpArgs dd ? ; Указатель на массив адресов строк
- lpArgStr dd ? ; Указатель на массив строк
- ends
Читать статью целиком »
Просмотров: 11880 | Комментариев: 16
Использование иконок разных размеров в ресурсах
12.02.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Большим плюсом Flat Assembler является то, что при разработке создается минимальное количество файлов. Описания ресурсов хранятся прямо в исходнике ASM, что тоже очень удобно. Например, в официальной документации и исходниках описание главной иконки в ресурсах исполняемого файла выглядит примерно так:Code (Assembler) : Убрать нумерацию
- section '.rsrc' resource data readable
- directory RT_ICON, icons,\
- RT_GROUP_ICON, group_icons
- resource icons,\
- 1, LANG_NEUTRAL, icon_data
- resource group_icons,\
- 1, LANG_NEUTRAL, main_icon
- ; Описание одиночной иконки
- icon main_icon, icon_data, 'main_icon.ico'
Code (Assembler) : Убрать нумерацию
- section '.rsrc' resource data readable
- directory RT_ICON, icons,\
- RT_GROUP_ICON, group_icons
- resource icons,\
- 1, LANG_NEUTRAL, icon_data1,\
- 2, LANG_NEUTRAL, icon_data2,\
- 3, LANG_NEUTRAL, icon_data3
- resource group_icons,\
- 1, LANG_NEUTRAL, main_icon
- ; Описание иконок разных размеров, объединенных в одну
- icon main_icon,\
- icon_data1, 'icon_16x16_32bit.ico',\
- icon_data2, 'icon_32x32_32bit.ico',\
- icon_data3, 'icon_48x48_32bit.ico'
Читать статью целиком »
Просмотров: 7789 | Комментариев: 5
Программное выключение монитора
08.02.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Выключить монитор из программы можно, но только если он совместим со стандартом EnergyStar. Об этом можно не беспокоиться, все современные мониторы удовлетворяют этому условию. Беспокоиться надо о другом. По непонятной причине с сайта на сайт упорно копируют один и тот же код на разных языках программирования, который якобы должен выключить монитор. Вот его вариант на Ассемблере:Code (Assembler) : Убрать нумерацию
- ; ВНИМАНИЕ! Это НЕПРАВИЛЬНЫЙ код!!!
- invoke GetDesktopWindow
- invoke SendMessage, eax, WM_SYSCOMMAND, SC_MONITORPOWER, 0
Но хватит о грустном. Правильный код программного выключения монитора будет таким:
Code (Assembler) : Убрать нумерацию
- ;-------------------------------------------------
- ; Правильный код выключения монитора
- ;-------------------------------------------------
- ; В FASM не определена константа HWND_BROADCAST, сделаем это самостоятельно
- HWND_BROADCAST = 0FFFFh
- ; Выключить монитор
- invoke SendMessage, HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2
Читать статью целиком »
Просмотров: 14530 | Комментариев: 20
Сортировка массива строк на Ассемблере
29.01.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Долго откладывал написание этой функции, но теперь вот прижало. Получилась функция сортировки массива произвольных текстовых строк в формате ASCIIZ усовершенствованным методом "пузырька". Усовершенствование заключается в том, что если при очередном проходе ни одной сортировки не было выполнено, то дальнейшая обработка массива прекращается. В некоторых случаях это дает значительный выигрыш в скорости работы. Однако, алгоритм сортировки "пузырьком" в любом случае является самым медленным, поэтому для очень больших массивов эта функция не подойдет. Но мне для больших объемов ее и не надо, на массиве из нескольких сотен или даже тысяч строк скорость работы функции меня вполне устраивает.Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------------------------
- ; Функция сортировки массива строк
- ; by ManHunter / PCL
- ; http://www.manhunter.ru
- ;
- ; Сортировка выполняется усовершенствованным методом "пузырька"
- ; Параметры:
- ; lpArray - указатель на массив адресов строк
- ; dFlag - метод сортировки: TRUE - по возрастанию,
- ; FALSE - по убыванию
- ; На выходе:
- ; отсортированный согласно правилу массив адресов строк
- ;------------------------------------------------------------------
- proc SortArray lpArray:dword, dFlag:dword
- pusha
- ; Указатель на массив адресов строк
- mov esi,[lpArray]
- mov ebx,[dFlag]
- sa_sort_1:
- ; Проверка на 0 - признак окончания массива
- mov eax,[esi]
- or eax,eax
- jz sa_stop_sort
- or bh,bh
- jnz sa_stop_sort
- ; Сравниваем, начиная со следующего элемента
- lea edi,[esi+4]
- ; Установить флаг, что сортировка не требуется,
- ; если дальнейший остаток массива уже отсортирован
- mov bh,1
- sa_sort_2:
- ; Следующий элемент 0 - массив закончился
- mov edx,[edi]
- or edx,edx
- jz sa_next_sort
- ; Сохранить текущие значения указателей
- push esi edi
- ; Указатели на строки
- mov esi,eax
- mov edi,edx
- sa_compare_string:
- ; Сравнить символы в строках
- mov cl,byte [edi]
- mov ch,byte [esi]
- ; Если символы равны, то сравнить следующие
- cmp cl,ch
- je sa_equal
- ; Проверка больше-меньше в зависимости от флага
- cmp bl,0
- jz @f
- cmp cl,ch
- ja ss_next_string
- jmp sa_change_offs
- @@:
- cmp cl,ch
- jb ss_next_string
- sa_change_offs:
- ; Поменять местами адреса строк
- xchg eax,edx
- ; Сбросить флаг, что сортировка не требуется
- xor bh,bh
- jmp ss_next_string
- sa_equal:
- ; Если закончилась строка, то перейти к следующей паре
- or cl,cl
- jz ss_next_string
- ; Перейти к следующей паре символов
- inc esi
- inc edi
- jmp sa_compare_string
- ss_next_string:
- ; Восстановить значения указателей и записать в них
- ; значения адресов строк, без разницы изменившихся или нет
- pop edi esi
- mov [esi],eax
- mov [edi],edx
- ; Перейти к следующему элементу массива
- add edi,4
- jmp sa_sort_2
- sa_next_sort:
- ; Перейти к следующему элементу массива
- add esi,4
- jmp sa_sort_1
- sa_stop_sort:
- popa
- ret
- endp
Читать статью целиком »
Просмотров: 18411 | Комментариев: 7
Рекурсивный обход дерева каталогов
19.01.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Обход дерева каталогов является одной из классических прикладных задач на применение рекурсии. В Windows штатных API-функций для этого нет, поэтому поиск файлов выполняется при помощи пары API-функций FindFirstFile и FindNextFile. Совершенно непонятно, почему разработчики Windows не дали возможность точно настраивать критерии поиска, ограничившись только маской имени файла. Даже в MS-DOS для решения аналогичной задачи можно было задать по крайней мере атрибуты файлов, например для поиска только каталогов. Более расширенные возможности для поиска предоставляет API-функция FindFirstFileEx, но она доступна только в операционной системе Windows 2000 и выше.Для рекурсивного обхода дерева каталогов я написал следующую функцию. Она сканирует дерево каталогов, начиная с указанного, и передает все найденные имена файлов в заданную функцию-обработчик. Все действия с найденными файлами выполняются уже в ней.
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------------------------
- ; Функция рекурсивного обхода дерева каталогов
- ; (C) ManHunter / PCL
- ; http://www.manhunter.ru
- ;
- ; Параметры вызова:
- ; lpFStr - указатель на начальный каталог без завершающего слеша.
- ; он должен быть в буфере размером не менее MAX_PATH байт
- ; lpProc - указатель на callback-функцию для передачи имен файлов,
- ; это обязательный параметр
- ; dFlag - флаг "передавать в callback-функцию имена найденных
- ; каталогов" (TRUE/FALSE)
- ;------------------------------------------------------------------
- proc FindFileRecursive lpFStr:dword,lpProc:dword,dFlag:dword
- local hFind:DWORD ; Локальный хэндл текущего поиска
- locals
- FndData WIN32_FIND_DATA ; Локальная структура WIN32_FIND_DATA
- endl
- ; Сохранить изменяемые регистры
- push ebx ecx edx
- ; Добавить к пути поиска '\*.*'
- invoke lstrcat,[lpFStr],ff_mask
- ; Найти первый файл
- lea eax,[FndData]
- push eax
- invoke FindFirstFile,[lpFStr]
- ; В случае ошибки полностью прекратить дальнейшее сканирование
- cmp eax,INVALID_HANDLE_VALUE
- jne @f
- xor eax,eax
- jmp ff_exit
- @@:
- ; Сохранить хэндл текущего поиска
- mov [hFind],eax
- ff_chk_file:
- ; Проверить имя файла на недопустимое
- lea eax,[FndData.cFileName]
- push eax
- ; Имя файла '.'
- invoke lstrcmp,ff_skip1
- or eax,eax
- ; Да, пропустить
- jz ff_next_file
- lea eax,[FndData.cFileName]
- push eax
- ; Имя файла '..'
- invoke lstrcmp,ff_skip2
- or eax,eax
- ; Да, пропустить
- jz ff_next_file
- ; Если установлен флаг dFlag=TRUE, то передавать в callback-процедуру
- ; все найденные результаты, в том числе и каталоги
- cmp [dFlag],0
- jne @f
- ; Установлен флаг передавать только файлы. Проверить атрибуты
- ; найденного файла
- mov eax,[FndData.dwFileAttributes]
- and eax,FILE_ATTRIBUTE_DIRECTORY
- ; Это каталог, пропустить
- jnz ff_do_not_callback
- @@:
- ; Вычислить длину текущей строки поиска и обрезать '*.*'
- invoke lstrlen,[lpFStr]
- sub eax,3
- add eax,[lpFStr]
- mov byte [eax],0
- push eax
- ; Дописать к пути имя найденного файла или каталога
- lea eax,[FndData.cFileName]
- push eax
- invoke lstrcat,[lpFStr]
- ; Передать имя файла в callback-функцию
- stdcall [lpProc],[lpFStr]
- ; Вернуть маску поиска на место
- pop ecx
- mov dword [ecx],'*.*'
- ; Если callback-функция вернула 0, то прекратить сканирование
- or eax,eax
- jz ff_stop_scan
- ; Это каталог?
- mov eax,[FndData.dwFileAttributes]
- and eax,FILE_ATTRIBUTE_DIRECTORY
- je ff_next_file
- ff_do_not_callback:
- ; Вычислить длину текущей строки поиска и обрезать '*.*'
- invoke lstrlen,[lpFStr]
- sub eax,3
- add eax,[lpFStr]
- mov byte [eax],0
- push eax
- ; Дописать к пути имя найденного каталога
- lea eax,[FndData.cFileName]
- push eax
- invoke lstrcat,[lpFStr]
- ; Рекурсивный вызов поиска файлов в новом каталоге
- stdcall FindFileRecursive,[lpFStr],[lpProc],[dFlag]
- ; Вернуть маску поиска на место
- pop ecx
- mov dword [ecx],'*.*'
- ; Если callback-функция вернула 0, то прекратить сканирование
- or eax,eax
- jz ff_stop_scan
- ff_next_file:
- ; Найти следующий файл
- lea eax,[FndData]
- push eax
- invoke FindNextFile,[hFind]
- or eax,eax
- ; Файл найден, обработать его
- jnz ff_chk_file
- ; По умолчанию установить флаг "продолжать сканирование"
- mov eax,TRUE
- ff_stop_scan:
- ; Закрыть хэндл текущего поиска
- push eax
- invoke FindClose,[hFind]
- pop eax
- ff_exit:
- ; Восстановить измененные регистры
- pop edx ecx ebx
- ; Возврат из процедуры.
- ; Код возврата EAX=1 - продолжать сканирование, EAX=0 - стоп
- ret
- ff_mask db '\*.*',0 ; Маска файлов для поиска
- ff_skip1 db '.',0 ; Запрещенное имя файла
- ff_skip2 db '..',0 ; Запрещенное имя файла
- endp
Читать статью целиком »
Просмотров: 9017 | Комментариев: 2