2015-05-13 1 views
0

Я пытаюсь создать сортировку пузыря со сборкой. Я сделал это успешно с почти идентичным кодом, только теперь я передаю массив LOCAL вместо одного, определенного в разделе .data. Все работает, но, похоже, нет переключения.Bubble sort не работает с локальным массивом на языке ассемблера

Вот код

start 

call main 

exit 


main PROC 
    LOCAL numArray[5]:DWORD ; Create a local array for the numbers 

    mov [numArray + 0], 5 
    mov [numArray + 4], 4 
    mov [numArray + 8], 3 
    mov [numArray + 12], 2 
    mov [numArray + 16], 1 

    push numArray 
    call BubbleSort 

    ret 

main ENDP 

array EQU [ebp + 8] 
FLAG EQU DWORD PTR [ebp - 4] 
BubbleSort PROC 
    enter 4, 0      ; Enter with one int local memory (for flag) 


    outer_bubble_loop: 
     mov ecx, 1     ; Set the count to 1 
     mov FLAG, 0     ; And clear the flag (Detects if anything changes 

     inner_bubble_loop:     ; Loop through all values 
      mov ebx, [array + ecx * 4 - 4] ; Move the (n - 1)th index to ebx 
      cmp ebx, [array + ecx * 4]  ; Compare ebx against the (n)th index 
      jle end_loop     ; If the result was less than or equal, skip the swapping part 


      mov ebx, [array + ecx * 4]  ; Move (n)  into ebx 
      mov edx, [array + ecx * 4 - 4] ; Move (n - 1) into edx 
      mov [array + ecx * 4], edx  ; Move (n - 1) into n 
      mov [array + ecx * 4 - 4], ebx ; Move (n)  into (n - 1) 
      mov FLAG, 1      ; Set the changed flag 

      end_loop:      ; End loop label 

      inc ecx       ; Increase the count 
      cmp ecx, NDATES     ; Check if we've made it to the end yet 

      jl inner_bubble_loop   ; If not, repeat the inner loop 

     cmp FLAG, 0     ; Check if we changed anything 
     je loop_end     ; If we didn't, go to the end 
     jmp outer_bubble_loop  ; (Else) Jump to the beginning of the loop 


     loop_end:     ; Loop end label 

    leave 
    ret 
BubbleSort ENDP 

Мой выход, странно:

Если я использую другой набор данных, он не выполняет дублирование, но все еще не перемещается.

В каком месте я ошибаюсь?

+0

В моей старой версии Masm директива 'LOCAL' используется только внутри макроса, чтобы заставить макрос генерировать уникальные идентификаторы для любых меток внутри макроса (поэтому они не дублируются в другом использовании макроса). –

+0

@WeatherVane, from * Язык ассемблера для x86-процессоров, 6-е издание *, «Мы можем догадаться, что Microsoft создала директиву LOCAL в качестве замены на уровне высокого уровня для инструкции ENTER. LOCAL объявляет одну или несколько локальных переменных по имени, назначая их размер атрибуты. (С другой стороны, ENTER сохраняет только один неназванный блок пространства стека для локальных переменных.) «Кроме того, примеры никогда не указывают, что они могут использоваться только в макросах. На самом деле, они даже не показывают их с помощью макросов. – David

+0

в качестве флюгера используется –

ответ

1

; push numArray 
lea eax, numArray 
push eax 
call BubbleSort 
... 

... если я не ошибаюсь ...

Edit: Ааа ... хуже. Я думаю, вам придется «разыгрывать» его в BubbleSort.

mov edx, array ; [ebp + 8], right? 
; then use edx instead of "array"... or so... 

Редактировать2; Упс, вы уже используете edx в свопе. Используйте esi или edi, затем ...

+0

Спасибо! Раньше у меня было разыменование, но оно не работало. Недостаток 'lea' был моей проблемой. – David

0

Вам не хватает ret после звонка на BubbleSort. Я не знаю, где вы устанавливаете BP для индексации фрейма стека, но при прохождении к второму выполнению BubbleSort стек не будет выравниваться одинаково.

call BubbleSort 
ret 

Или выйти из исполнения кода.

+0

Оба там, просто забыли положить их, когда я сжал свой код. – David

+0

Программа не рушится, она просто не сортируется. – David

+0

Я не думаю, что с 'mov [numArray + 0], 5', где нет упоминания' BP', что это происходит в сегменте данных? –

Смежные вопросы