简体   繁体   English

汇编程序中的插入排序不排序

[英]Insertion sort in assembler doesn't sort

I'm trying to sort a array of numbers by Insertion sort but it not sort the numbers correctly. 我正在尝试通过插入排序对数字数组进行排序,但是它无法正确对数字进行排序。 I've tried everything but it does not sort them As it should. 我已经尝试了所有方法,但未按要求对其进行排序。 I would be happy if you could help me figure out where the problem and on how I can fix it thanks !! 如果您能帮助我找出问题所在以及如何解决该问题,我将非常感谢!

section .rodata
MSG:    DB  "welcome to sortMe, please sort me",10,0
S1: DB  "%d",10,0 ; 10 = '\n' , 0 = '\0'

section .data

array   DB 5,1,7,3,4,9,12,8,10,2,6,11   ; unsorted array
len DB 12   

section .text
align 16
global main
extern printf

main:
push MSG    ; print welcome message
call printf
add esp,4   ; clean the stack 

call printArray ;print the unsorted array

    push ebp        ;save old frame pointer
    mov ebp,esp     ;create new frame on stack
    pusha
    mov esi,array
    mov ecx,8
 OuterLoop:
    mov ebx,ecx
    InnerLoop:
            add esi,ebx ;basically makes array[0] to array[ebx]
            mov eax,[esi] ;eax=array[ebx]
            sub esi,8
            mov edx,[esi] ; edx=array[ebx-1]
            add esi,8
            cmp eax,edx ; if(eax<edx)
            jle skip2 ; skip the loop
            ;else:
            mov [esi],edx ;array[ebx]=array[ebx-1]
            sub esi,8
            mov [esi],eax ; array[ebx-1]=array[ebx]
            add esi,8
            sub esi,ebx ; return the array to its original state (array[0])
            sub ebx,8
            cmp ebx,0
            jne InnerLoop
    skip1:
    add ecx,8
    cmp ecx,96
    jle OuterLoop

    popa            ;restore registers
    mov esp,ebp     ;clean the stack frame
    pop ebp
    push MSG        ; print welcome message (to divide between the unsorted and sorted)
    call printf
    add esp,4       ; clean the stack
    call printArray        

    mov eax, 1      ;exit system call
    int 0x80


printArray:
push ebp    ;save old frame pointer
mov ebp,esp ;create new frame on stack
pusha       ;save registers

mov eax,0
mov ebx,0
mov edi,0

mov esi,0   ;array index
mov bl,byte[len]
add edi,ebx ; edi = array size

print_loop:
cmp esi,edi
je print_end
mov al ,byte[array+esi] ;set num to print in eax
push eax
push S1
call printf
add esp,8   ;clean the stack
inc esi
jmp  print_loop
print_end:
popa        ;restore registers
mov esp,ebp ;clean the stack frame
pop ebp     ;return to old stack frame
ret

skip2:
sub esi,ebx ; return the array to the original state
jmp skip1

You're horribly mixing 3 sizes! 您在混合3种尺寸!
1. Array of bytes 1.字节数组
2. Values of dwords 2. dwords的值
3. Steps of qwords 3. qwords步骤

Once you've decided what size to use beware of this code. 一旦确定了要使用的大小,请当心此代码。 In its current qword form it does an extra iteration! 以其当前的qword形式,它会进行额外的迭代! (use jl OuterLoop ) (使用jl OuterLoop

cmp ecx,96
jle OuterLoop

Why don't you use MOVZX to EAX in this line? 您为什么不在这一行中使用MOVZX转EAX? It's much cleaner. 干净得多。

mov al ,byte[array+esi] ;set num to print in eax

The same applies to 同样适用于

mov bl,byte[len]

By putting mov esi,array right after OuterLoop: you can avoid that ugly detour via SKIP2. 通过将mov esi,array放在OuterLoop:之后OuterLoop:您可以通过SKIP2避免这种难看的弯路。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM