Сортировка массива от наибольшего к минимальному на ассемблере x86 - PullRequest
0 голосов
/ 24 мая 2019

Я пытаюсь отсортировать массив, используя регистры от наибольшего к меньшему, и, похоже, ничего не работает.Ecx - это мое количество цифр, esi - адрес моего списка, состоящего из слов.Я использую edx, чтобы продолжать увеличиваться на 4 байта для каждого элемента.Мой код не сортирует весь массив, я знаю, что мне нужно найти местоположение максимума, а затем установить его равным edx внешних циклов, но я не могу понять, как изменить элементы в массиве, потому что яиметь только регистр edx.Я попытался выдвинуть местоположение, а затем вытащить его обратно, когда внутренний цикл был закончен, но, похоже, это не сработало.Пожалуйста, оцените все, что я работаю над этой проблемой более 4 часов.

push    ebp
mov     ebp,esp
mov     ecx,[ebp+8]
mov     esi,[ebp+12]
mov     edx,-4

outerloop:
add     edx,4
push    edx
push    ecx
mov     ebx,[edx+esi]

innerloop:
add     edx,4
mov     eax,[edx+esi]
cmp     ebx,eax
jl      change
finish:
loop    innerloop
pop     ecx
pop     edx
loop    outerloop
jmp     done


change:
mov     [edx+esi],ebx
mov     [edx+esi-4],eax
sub     edx,4
push    edx
mov     edx,offset change1
call    writestring
pop     edx
jmp     finish

done:
pop     ebp
ret     8

1 Ответ

0 голосов
/ 24 мая 2019

То, что вы ищете, это «перевернутая» Bubble Sort (Конечно, вы можете использовать любой алгоритм сортировки, который вы хотите, но это просто для примера).Я не уверен, какой ассемблер вы используете, но вот короткая функция ассемблера, которая выполнит что-то вроде n int32_t целых чисел, хранящихся в массиве / списке arr.(Этот пример был написан в NASM)

;int *sort(int *arr,int n);
sort:
    push ebp
    mov ebp,esp
    mov edx,[ebp+12]

.loop1:
    mov esi,[ebp+8] ;arr ptr
    mov ecx,[ebp+12] ;n number of ints

.loop2:
    mov eax,[esi] ;compare
    mov ebx,[esi+4]
    cmp eax,ebx
    jg .skip

    mov [esi],ebx ;swap
    mov [esi+4],eax

.skip:
    add esi,4 ;perform loop checks
    dec ecx
    cmp ecx,1
    ja .loop2
    dec edx
    ja .loop1

    mov eax,[ebp+8] ;return arr

    mov esp,ebp
    pop ebp
    ret

Пожалуйста, имейте в виду, что этот пример не был действительно оптимизирован (например, он повторяет слишком много раз по всему массиву).Иногда (особенно на языках ассемблера), чем меньше, тем лучше.Вместо смещения указателя с помощью ecx / edx, вы можете увеличить указатель массива (или его копию) и выполнить сравнение, используя это напрямую.Таким образом, вам не нужно одновременно отслеживать регистр счетчика и указатель.:)

...