Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Сортировка массива строк на Ассемблере

29.01.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Долго откладывал написание этой функции, но теперь вот прижало. Получилась функция сортировки массива произвольных текстовых строк в формате ASCIIZ усовершенствованным методом "пузырька". Усовершенствование заключается в том, что если при очередном проходе ни одной сортировки не было выполнено, то дальнейшая обработка массива прекращается. В некоторых случаях это дает значительный выигрыш в скорости работы. Однако, алгоритм сортировки "пузырьком" в любом случае является самым медленным, поэтому для очень больших массивов эта функция не подойдет. Но мне для больших объемов ее и не надо, на массиве из нескольких сотен или даже тысяч строк скорость работы функции меня вполне устраивает.
  1. ;------------------------------------------------------------------
  2. ; Функция сортировки массива строк
  3. ; by ManHunter / PCL
  4. ; http://www.manhunter.ru
  5. ;
  6. ; Сортировка выполняется усовершенствованным методом "пузырька"
  7. ; Параметры:
  8. ; lpArray - указатель на массив адресов строк
  9. ; dFlag   - метод сортировки: TRUE - по возрастанию,
  10. ;           FALSE - по убыванию
  11. ; На выходе:
  12. ; отсортированный согласно правилу массив адресов строк
  13. ;------------------------------------------------------------------
  14. proc    SortArray lpArray:dword, dFlag:dword
  15.         pusha
  16.  
  17.         ; Указатель на массив адресов строк
  18.         mov     esi,[lpArray]
  19.  
  20.         mov     ebx,[dFlag]
  21. sa_sort_1:
  22.         ; Проверка на 0 - признак окончания массива
  23.         mov     eax,[esi]
  24.         or      eax,eax
  25.         jz      sa_stop_sort
  26.  
  27.         or      bh,bh
  28.         jnz     sa_stop_sort
  29.  
  30.         ; Сравниваем, начиная со следующего элемента
  31.         lea     edi,[esi+4]
  32.  
  33.         ; Установить флаг, что сортировка не требуется,
  34.         ; если дальнейший остаток массива уже отсортирован
  35.         mov     bh,1
  36. sa_sort_2:
  37.         ; Следующий элемент 0 - массив закончился
  38.         mov     edx,[edi]
  39.         or      edx,edx
  40.         jz      sa_next_sort
  41.  
  42.         ; Сохранить текущие значения указателей
  43.         push    esi edi
  44.  
  45.         ; Указатели на строки
  46.         mov     esi,eax
  47.         mov     edi,edx
  48. sa_compare_string:
  49.         ; Сравнить символы в строках
  50.         mov     cl,byte [edi]
  51.         mov     ch,byte [esi]
  52.         ; Если символы равны, то сравнить следующие
  53.         cmp     cl,ch
  54.         je      sa_equal
  55.  
  56.         ; Проверка больше-меньше в зависимости от флага
  57.         cmp     bl,0
  58.         jz      @f
  59.  
  60.         cmp     cl,ch
  61.         ja      ss_next_string
  62.         jmp     sa_change_offs
  63. @@:
  64.         cmp     cl,ch
  65.         jb      ss_next_string
  66.  
  67. sa_change_offs:
  68.         ; Поменять местами адреса строк
  69.         xchg    eax,edx
  70.         ; Сбросить флаг, что сортировка не требуется
  71.         xor     bh,bh
  72.         jmp     ss_next_string
  73.  
  74. sa_equal:
  75.         ; Если закончилась строка, то перейти к следующей паре
  76.         or      cl,cl
  77.         jz      ss_next_string
  78.  
  79.         ; Перейти к следующей паре символов
  80.         inc     esi
  81.         inc     edi
  82.         jmp     sa_compare_string
  83.  
  84. ss_next_string:
  85.         ; Восстановить значения указателей и записать в них
  86.         ; значения адресов строк, без разницы изменившихся или нет
  87.         pop     edi esi
  88.         mov     [esi],eax
  89.         mov     [edi],edx
  90.  
  91.         ; Перейти к следующему элементу массива
  92.         add     edi,4
  93.         jmp     sa_sort_2
  94.  
  95. sa_next_sort:
  96.         ; Перейти к следующему элементу массива
  97.         add     esi,4
  98.         jmp     sa_sort_1
  99.  
  100. sa_stop_sort:
  101.         popa
  102.         ret
  103. endp
Сортировать сами строки в памяти слишком нерационально, поэтому для сортировки нам понадобится массив DWORD'ов с указателями на строки. Параметр lpArray - указатель на такой массив. Признак окончания массива - DWORD с нулевым значением. Параметр dFlag определяет в каком порядке будет отсортирован массив: по возрастанию (значение TRUE) или по убыванию (значение FALSE). На выходе получаем отсортированный массив указателей.

Читать статью целиком »
Просмотров: 18559 | Комментариев: 7

Концерт группы Haggard в "Точке"

26.01.2009 | Категория: Жизнь в оффлайне | Автор: ManHunter

Концерт группы Haggard

Первая попытка попасть на этот концерт была неудачной, его перенесли с 25-го ноября на 2-е декабря. Только зря в снег и ветер тащился в другой конец города чтобы полюбоваться на объявление на дверях клуба. Однако и через неделю в клубе меня ждало разочарование, клуб украшало такое же объявление об отмене и переносе концерта на середину января. Мощный луч диареи в сторону ответственных за обновление сайта клуба за то, что информация о переносах в обеих случаях появлялась чуть ли не во время запланированного начала концерта.

Читать статью целиком »
Просмотров: 4710 | Комментариев: 4

Apache Server Control 1.1a

23.01.2009 | Категория: Мои программы | Автор: ManHunter

Скриншот программы Apache Server Control

Еще одна программа, написанная для личных нужд. Apache Server Control позволяет управлять HTTP-сервером Apache версий 1.3.x под Windows: запускать, останавливать и перезапускать его службу. В дистрибутивах Apache 2.x аналогичная программа уже имеется. Кроме управления сервером вы можете редактировать файлы hosts и httpd.conf прямо в окне Apache Server Control. Программа должна находиться в одном каталоге с установленным Apache, тогда все пути к нужным файлам будут определены автоматически. Я использую Apache Server Control когда надо по-быстрому добавить локальный хост, прописать его во все настройки и перезапустить Apache. Может еще кому пригодится.

Читать статью целиком »
Просмотров: 5183 | Комментариев: 5

"Ленивые" картофельные шаньги

21.01.2009 | Категория: А еще я туда ем! | Автор: ManHunter

"Ленивые" картофельные шаньги

Этот рецепт я подсмотрел в детстве у своей бабушки, а теперь он меня иногда выручает. Бывают такие ситуации, когда совершенно нет времени возиться на кухне, а хочется приготовить что-нибудь вкусное. Или приходят нежданные гости, а угостить их нечем. Тут вам пригодятся "ленивые" шаньги. Готовятся они очень быстро и просто, не требуют больших финансовых затрат и труднодоступных продуктов. Обычно все необходимое уже есть дома, даже не приходится идти в магазин.

Читать статью целиком »
Просмотров: 22156 | Комментариев: 25

Рекурсивный обход дерева каталогов

19.01.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Обход дерева каталогов является одной из классических прикладных задач на применение рекурсии. В Windows штатных API-функций для этого нет, поэтому поиск файлов выполняется при помощи пары API-функций FindFirstFile и FindNextFile. Совершенно непонятно, почему разработчики Windows не дали возможность точно настраивать критерии поиска, ограничившись только маской имени файла. Даже в MS-DOS для решения аналогичной задачи можно было задать по крайней мере атрибуты файлов, например для поиска только каталогов. Более расширенные возможности для поиска предоставляет API-функция FindFirstFileEx, но она доступна только в операционной системе Windows 2000 и выше.

Для рекурсивного обхода дерева каталогов я написал следующую функцию. Она сканирует дерево каталогов, начиная с указанного, и передает все найденные имена файлов в заданную функцию-обработчик. Все действия с найденными файлами выполняются уже в ней.
  1. ;------------------------------------------------------------------
  2. ; Функция рекурсивного обхода дерева каталогов
  3. ; (C) ManHunter / PCL
  4. ; http://www.manhunter.ru
  5. ;
  6. ; Параметры вызова:
  7. ; lpFStr - указатель на начальный каталог без завершающего слеша.
  8. ;          он должен быть в буфере размером не менее MAX_PATH байт
  9. ; lpProc - указатель на callback-функцию для передачи имен файлов,
  10. ;          это обязательный параметр
  11. ; dFlag  - флаг "передавать в callback-функцию имена найденных
  12. ;          каталогов" (TRUE/FALSE)
  13. ;------------------------------------------------------------------
  14. proc    FindFileRecursive lpFStr:dword,lpProc:dword,dFlag:dword
  15.         local   hFind:DWORD     ; Локальный хэндл текущего поиска
  16.  
  17.         locals
  18.         FndData WIN32_FIND_DATA ; Локальная структура WIN32_FIND_DATA
  19.         endl
  20.  
  21.         ; Сохранить изменяемые регистры
  22.         push    ebx ecx edx
  23.  
  24.         ; Добавить к пути поиска '\*.*'
  25.         invoke  lstrcat,[lpFStr],ff_mask
  26.  
  27.         ; Найти первый файл
  28.         lea     eax,[FndData]
  29.         push    eax
  30.         invoke  FindFirstFile,[lpFStr]
  31.         ; В случае ошибки полностью прекратить дальнейшее сканирование
  32.         cmp     eax,INVALID_HANDLE_VALUE
  33.         jne     @f
  34.         xor     eax,eax
  35.         jmp     ff_exit
  36. @@:
  37.         ; Сохранить хэндл текущего поиска
  38.         mov     [hFind],eax
  39.  
  40. ff_chk_file:
  41.         ; Проверить имя файла на недопустимое
  42.         lea     eax,[FndData.cFileName]
  43.         push    eax
  44.         ; Имя файла '.'
  45.         invoke  lstrcmp,ff_skip1
  46.         or      eax,eax
  47.         ; Да, пропустить
  48.         jz      ff_next_file
  49.  
  50.         lea     eax,[FndData.cFileName]
  51.         push    eax
  52.         ; Имя файла '..'
  53.         invoke  lstrcmp,ff_skip2
  54.         or      eax,eax
  55.         ; Да, пропустить
  56.         jz      ff_next_file
  57.  
  58.         ; Если установлен флаг dFlag=TRUE, то передавать в callback-процедуру
  59.         ; все найденные результаты, в том числе и каталоги
  60.         cmp     [dFlag],0
  61.         jne     @f
  62.  
  63.         ; Установлен флаг передавать только файлы. Проверить атрибуты
  64.         ; найденного файла
  65.         mov     eax,[FndData.dwFileAttributes]
  66.         and     eax,FILE_ATTRIBUTE_DIRECTORY
  67.         ; Это каталог, пропустить
  68.         jnz     ff_do_not_callback
  69. @@:
  70.         ; Вычислить длину текущей строки поиска и обрезать '*.*'
  71.         invoke  lstrlen,[lpFStr]
  72.         sub     eax,3
  73.         add     eax,[lpFStr]
  74.         mov     byte [eax],0
  75.         push    eax
  76.  
  77.         ; Дописать к пути имя найденного файла или каталога
  78.         lea     eax,[FndData.cFileName]
  79.         push    eax
  80.         invoke  lstrcat,[lpFStr]
  81.         ; Передать имя файла в callback-функцию
  82.         stdcall [lpProc],[lpFStr]
  83.  
  84.         ; Вернуть маску поиска на место
  85.         pop     ecx
  86.         mov     dword [ecx],'*.*'
  87.  
  88.         ; Если callback-функция вернула 0, то прекратить сканирование
  89.         or      eax,eax
  90.         jz      ff_stop_scan
  91.  
  92.         ; Это каталог?
  93.         mov     eax,[FndData.dwFileAttributes]
  94.         and     eax,FILE_ATTRIBUTE_DIRECTORY
  95.         je      ff_next_file
  96.  
  97. ff_do_not_callback:
  98.         ; Вычислить длину текущей строки поиска и обрезать '*.*'
  99.         invoke  lstrlen,[lpFStr]
  100.         sub     eax,3
  101.         add     eax,[lpFStr]
  102.         mov     byte [eax],0
  103.         push    eax
  104.  
  105.         ; Дописать к пути имя найденного каталога
  106.         lea     eax,[FndData.cFileName]
  107.         push    eax
  108.         invoke  lstrcat,[lpFStr]
  109.  
  110.         ; Рекурсивный вызов поиска файлов в новом каталоге
  111.         stdcall FindFileRecursive,[lpFStr],[lpProc],[dFlag]
  112.  
  113.         ; Вернуть маску поиска на место
  114.         pop     ecx
  115.         mov     dword [ecx],'*.*'
  116.  
  117.         ; Если callback-функция вернула 0, то прекратить сканирование
  118.         or      eax,eax
  119.         jz      ff_stop_scan
  120.  
  121. ff_next_file:
  122.         ; Найти следующий файл
  123.         lea     eax,[FndData]
  124.         push    eax
  125.         invoke  FindNextFile,[hFind]
  126.         or      eax,eax
  127.         ; Файл найден, обработать его
  128.         jnz     ff_chk_file
  129.         ; По умолчанию установить флаг "продолжать сканирование"
  130.         mov     eax,TRUE
  131. ff_stop_scan:
  132.         ; Закрыть хэндл текущего поиска
  133.         push    eax
  134.         invoke  FindClose,[hFind]
  135.         pop     eax
  136. ff_exit:
  137.         ; Восстановить измененные регистры
  138.         pop     edx ecx ebx
  139.  
  140.         ; Возврат из процедуры.
  141.         ; Код возврата EAX=1 - продолжать сканирование, EAX=0 - стоп
  142.         ret
  143.  
  144. ff_mask  db '\*.*',0    ; Маска файлов для поиска
  145. ff_skip1 db '.',0       ; Запрещенное имя файла
  146. ff_skip2 db '..',0      ; Запрещенное имя файла
  147.  
  148. endp
Путь к начальному каталогу должен размещаться в буфере размером не менее определенного в системе MAX_PATH (обычно 256 символов). Обязательным параметром является адрес callback-функции RecursiveFindFileProc, которой поочередно передаются все результаты поиска. Флаг dFlag указывает, будут передаваться в callback-функцию все найденные результаты, включая каталоги, или же будут передаваться только найденные файлы. Код возврата из FindFileRecursive EAX=1 - сканирование было закончено, когда больше ни одного файла не было найдено, EAX=0 - сканирование завершилось аварийно или же было остановлено из callback-функции.

Читать статью целиком »
Просмотров: 9086 | Комментариев: 2

01 ... 407 408 409 410 411 412 413 ... 422
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.1 сек. / MySQL: 2 (0.0333 сек.) / Память: 4.5 Mb
Наверх