Долго откладывал написание этой функции, но теперь вот прижало. Получилась функция сортировки массива произвольных текстовых строк в формате ASCIIZ усовершенствованным методом "
пузырька". Усовершенствование заключается в том, что если при очередном проходе ни одной сортировки не было выполнено, то дальнейшая обработка массива прекращается. В некоторых случаях это дает значительный выйгрыш в скорости работы. Однако, алгоритм сортировки "пузырьком" в любом случае является самым медленным, поэтому для очень больших массивов эта функция не подойдет. Но мне для больших объемов ее и не надо, на массиве из нескольких сотен или даже тысяч строк скорость работы функции меня вполне устраивает.
;------------------------------------------------------------------
; Функция сортировки массива строк
; 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
Сортировать сами строки в памяти слишком нерационально, поэтому для сортировки нам понадобится массив DWORD'ов с указателями на строки. Параметр lpArray - указатель на такой массив. Признак окончания массива - DWORD с нулевым значением. Параметр dFlag определяет в каком порядке будет отсортирован массив: по возрастанию (значение TRUE) или по убыванию (значение FALSE). На выходе получаем отсортированный массив указателей.
В приложении два примера использования функции SortArray. Первый обрабатывает несколько предустановленных значений. Второй написан для оценки скорости работы функции сортировки, он генерирует 10000 случайных строк и затем их упорядочивает.