Реализация быстрой сортировки (ассемблерная вставка в функцию на C++) - Assembler
Формулировка задачи:
Помогите выполнить реализацию быстрой сортировки. Написать код быстрой сортировки на ассемблере и сделать ассемблерную вставку в функцию на C++.
Нашёл такой код, а как его впихнуть в плюсы не знаю.
push offset array+n*4-4;указатель на последний элемент push offset array;указатель на первый элемент массива call quick_sort ; quicksort (data, data+n-1) ;----------------------------------------------------- partition proc Lb:dword, Ub:dword ; функция partition возвращает адрес pivot mov edx,Ub sub edx,eax ;eax=Lb shr edx,3 ;(Ub-Lb)/2 ; После завершения этого цикла все значения слева от элемента pivot ; будут меньше значения элемента pivot, а все значения справа от ; элемента pivot будут больше, чем значение элемента pivot mov edi,[eax+edx*4] ;получаем указатель на pivot ;pivot = *(Lb+(Ub-Lb)/2) cmp eax,Ub ;eax=Lb ja short b0 ;return Lb; ; Поиск значения, большего чем pivot, в нижней части массива b1: mov eax,Lb cmp [eax],edi ;edi=pivot jnl short b3 ;while (*Lb < pivot) add Lb,4 ;Lb++; jmp short b1 ; Поиск значения, меньшего чем pivot, в верхней части массива b4: sub Ub,4 b3: mov eax,Ub cmp [eax],edi ;while (*Ub > pivot) jg short b4 ;Ub-- mov ecx,Lb cmp ecx,eax ;eax=Ub ja short b5 ;if(Lb <= Ub) sub Ub,4 ;swap( Lb++, Ub-- ) add Lb,4 mov edx,[eax] ;eax=Ub xchg edx,[ecx] ;ecx=Lb mov [eax],edx ;*Ub<-->*Lb; b5: mov eax,Lb cmp eax,Ub jbe short b1 ;while (*Lb < pivot) b0: pop ebp retn 8 partition endp ;------------------------------------------------------------ quick_sort proc Lb:dword, Ub:dword mov eax,Lb cmp eax,Ub ; if (Lb >= Ub) jnb short exit1 ;сортировать нечего push Ub push eax ;eax=Lb call partition mov edi,eax ;eax=pivot_ptr sub eax,4 ;pivot_ptr-1 push eax push Lb call quick_sort ;отсортируем то, что слева от pivot push Ub push edi ;edi=pivot_ptr call quick_sort ; и то, что справа от pivot exit1: pop ebp retn 8 quick_sort endp
Решение задачи: «Реализация быстрой сортировки (ассемблерная вставка в функцию на C++)»
textual
Листинг программы
extern"C" void __cdecl quick_sort(int*, int*); //для вызова по правилам Си, а не С++ extern "C" int* __cdecl partition(int*, int*); //функция partition возвращает адрес pivot int* partition(int *Lb, int *Ub) { int *pivot_ptr; __asm { mov edx, Ub mov eax, Lb sub edx, eax shr edx,3 //(Ub-Lb)/2 // После завершения этого цикла все значения слева от элемента pivot // будут меньше значения элемента pivot, а все значения справа от // элемента pivot будут больше, чем значение элемента pivot mov edi, [eax+edx*4] //получаем указатель на pivot //pivot = *(Lb+(Ub-Lb)/2) cmp eax, Ub //eax=Lb ja b0 //return Lb; // Поиск значения, большего чем pivot, в нижней части массива b1: mov eax, Lb cmp [eax], edi //edi=pivot jnl b3 //while (*Lb < pivot) add Lb, 4 //Lb++; jmp short b1 // Поиск значения, меньшего чем pivot, в верхней части массива b4: sub Ub, 4 b3: mov eax, Ub cmp [eax], edi //while (*Ub > pivot) jg b4 //Ub-- mov ecx, Lb cmp ecx, eax //eax=Ub ja b5 //if(Lb <= Ub) sub Ub, 4 //swap( Lb++, Ub-- ) add Lb, 4 mov edx, [eax] //eax=Ub xchg edx, [ecx] //ecx=Lb mov [eax], edx //*Ub<-->*Lb; b5: mov eax, Lb cmp eax, Ub jbe b1 //while (*Lb < pivot) b0: mov pivot_ptr, eax } return pivot_ptr; } //------------------------------------------------------------ void quick_sort(int *Lb, int *Ub) { __asm { mov eax, Lb cmp eax, Ub //if (Lb >= Ub) jnb exit1 //сортировать нечего push Ub push eax //eax=Lb call partition add esp, 8 mov edi, eax //eax=pivot_ptr sub eax, 4 //pivot_ptr-1 push eax push Lb call quick_sort //отсортируем то, что слева от pivot add esp, 8 push Ub push edi //edi=pivot_ptr call quick_sort //и то, что справа от pivot add esp, 8 exit1: } } int main() { int ar[10] = {3,7,5,9,1,3,5,3,6,4}; quick_sort(&ar[0],&ar[9]); return 0; }
Объяснение кода листинга программы
- Функция partition реализует быструю сортировку, разделяя массив на две части: элементы, меньшие или равные опорному элементу (pivot), и элементы, большие опорного. Функция возвращает указатель на опорный элемент.
- В функции quick_sort происходит рекурсивная сортировка массива. Если размер массива меньше или равен 1, то считается, что сортировать нечего и функция завершается. В противном случае, происходит следующее:
- В стеке сохраняются указатели на границы сортируемого массива (Lb и Ub).
- Вызывается функция partition для поиска опорного элемента.
- Опорный элемент помещается между Lb и Ub, т.е. элементы, меньшие или равные опорному, перемещаются влево, а элементы, большие опорного, перемещаются вправо.
- Рекурсивно вызывается функция quick_sort для сортировки элементов, находящихся слева от опорного, и элементов, находящихся справа от опорного.
- В функции main создается массив из 10 целых чисел и вызывается функция quick_sort для его сортировки.
- Значения переменных в функции main:
- ar - указатель на массив из 10 целых чисел.
- Lb и Ub - указатели на границы сортируемого подмассива.
- pivot_ptr - указатель на опорный элемент.
- eax, edx - регистры процессора, используемые в ассемблерных вставках.
- b0, b1, b3, b4, b5 - метки, используемые в ассемблерных вставках.
- exit1 - метка завершения функции quick_sort при отсутствии элементов для сортировки.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д