Реализация быстрой сортировки (ассемблерная вставка в функцию на 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;
}

Объяснение кода листинга программы

  1. Функция partition реализует быструю сортировку, разделяя массив на две части: элементы, меньшие или равные опорному элементу (pivot), и элементы, большие опорного. Функция возвращает указатель на опорный элемент.
  2. В функции quick_sort происходит рекурсивная сортировка массива. Если размер массива меньше или равен 1, то считается, что сортировать нечего и функция завершается. В противном случае, происходит следующее:
    • В стеке сохраняются указатели на границы сортируемого массива (Lb и Ub).
    • Вызывается функция partition для поиска опорного элемента.
    • Опорный элемент помещается между Lb и Ub, т.е. элементы, меньшие или равные опорному, перемещаются влево, а элементы, большие опорного, перемещаются вправо.
    • Рекурсивно вызывается функция quick_sort для сортировки элементов, находящихся слева от опорного, и элементов, находящихся справа от опорного.
  3. В функции main создается массив из 10 целых чисел и вызывается функция quick_sort для его сортировки.
  4. Значения переменных в функции main:
    • ar - указатель на массив из 10 целых чисел.
    • Lb и Ub - указатели на границы сортируемого подмассива.
    • pivot_ptr - указатель на опорный элемент.
    • eax, edx - регистры процессора, используемые в ассемблерных вставках.
    • b0, b1, b3, b4, b5 - метки, используемые в ассемблерных вставках.
    • exit1 - метка завершения функции quick_sort при отсутствии элементов для сортировки.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4.111 из 5
Похожие ответы