How to update array after BubbleSort - asm in vc++
I'm learning the basics of bubblesort in Assembly right now and what I've coded makes sense in my head, but apparently not to the compiler. When I print out the entire array after running this subroutine, why does the array look the same as before it was sorted?
bubblesort proc
bubbleSort Proc
mov ecx, NUMS_LENGTH
dec ecx
mov edi, 0
.WHILE ecx > 0
mov ax, NUMS[di]
.IF ax > NUMS[di]+2
xchg ax, NUMS[di]+2
call WriteInt
mov [NUMS[di]+2], ax
inc di
.ENDIF
dec ecx
.ENDW
bubbleSort endp
Advice and insight are greatly appreciated. Many thanks in advance!
EDIT
bubbleSort Proc
mov ecx, NUMS_LENGTH
dec ecx
mov edi, 0
.WHILE ecx > 0
mov di, NUMS_LENGTH-1
.WHILE di < NUMS_LENGTH-1
mov ax, NUMS[di]
.IF ax > NUMS[di]+2
xchg ax, NUMS[di]+2
mov [NUMS[di]+2], ax
inc di
.ELSE
inc di
.ENDIF
.ENDW
dec ecx
.ENDW
bubbleSort endp
*EDIT 2 *
bubbleSort Proc
mov ecx, NUMS_LENGTH
dec ecx
mov di, 0
.WHILE ecx > 0
mov ax, NUMS[di]
.WHILE di != NUM开发者_开发百科S_LENGTH-1
.IF ax > NUMS[di]+2
xchg ax, NUMS[di]+2
mov NUMS[di]+2, ax
inc di
.ELSE
inc di
mov NUMS[di]+2, ax
.ENDIF
.ENDW
dec ecx
.ENDW
bubbleSort endp
At a guess, it doesn't look quite the same, but it's not sorted either.
A bubble sort requires two nested loops, but you seem to only have one loop. That means it makes only one pass through the array. At the end of one pass, the last element in the array will be in the correct position, but the rest won't be sorted yet.
Edit: The edited code probably isn't an improvement. In particular:
mov di, NUMS_LENGTH-1
.WHILE di < NUMS_LENGTH-1
We're setting di
equal to NUMS_LENGTH-1
, then executing a while loop that can only execute if di is less than NUMS_LENGTH-1, so that inner loop clearly won't (ever!) execute.
Edit2: Though a bubble sort in assembly language strikes me as just about the worst wast of time possible, I suppose if you insist, the obvious way to start would be to consider how a bubble sort looks in something like C:
for (int i=array_len; i!=0; --i)
for (int j=0; j<i; j++)
if (array[j] > array[j+1]) {
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
Writing something on the same general order in assembly language shouldn't be terribly difficult.
Edit4: Fixed code (I think):
mov ecx, (NUMS_LEN-1)*4
outer_loop:
xor edi, edi
inner_loop:
mov eax, nums[edi]
cmp eax, nums[edi+4]
jl noswap
xchg nums[edi+4], eax
mov nums[edi], eax
noswap:
add edi, 4
cmp edi, ecx
jl inner_loop
sub ecx, 4
jnz outer_loop
Sorry -- I've never really gotten used to Microsoft's "high level" control-flow macros for assembly language. A couple of points to consider: at least assuming we don't allow a zero-length array, for this task loops that test the condition at the bottom are a lot simpler. In general, loops that test at the bottom are cleaner in assembly language anyway. When the algorithm demands a test at the beginning, it's still often cleaner to put the test at the bottom, and build a structure like:
initalization
jmp loop_test
loop_top:
loop body
loop_test:
update loop variable(s)
if (more iterations)
jmp loop_top
精彩评论