x86(masm32)中的冒泡排序,我编写的排序不';行不通

x86(masm32)中的冒泡排序,我编写的排序不';行不通,x86,masm32,X86,Masm32,我正在尝试用x86(masm32)编写一个冒泡排序。这样不行。我已经测试了一些代码,在比较和交换部分,它似乎是一团糟。 出于某种原因,比较函数总是将2分配给EAX。如果我能弄明白为什么我能让程序工作 提前谢谢你的帮助 .data aa DWORD 10 DUP(5, 7, 6, 1, 4, 3, 9, 2, 10, 8) count DWORD 0 ; DB 8-bits, DW 16-bit, DWORD 32, WORD 16 BYTE 8

我正在尝试用x86(masm32)编写一个冒泡排序。这样不行。我已经测试了一些代码,在比较和交换部分,它似乎是一团糟。 出于某种原因,比较函数总是将2分配给EAX。如果我能弄明白为什么我能让程序工作

提前谢谢你的帮助

    .data
          aa DWORD 10 DUP(5, 7, 6, 1, 4, 3, 9, 2, 10, 8)
        count DWORD 0
; DB 8-bits, DW 16-bit, DWORD 32, WORD 16 BYTE 8



    .code                       ; Tell MASM where the code starts

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

start:                          ; The CODE entry point to the program

    mov esi, count ;loop count

    outer:
        inc esi
        mov edi, count        
        cmp esi, 9       
        je end_loop

    inner: ;this loop represents a full pass on the entire array
        inc edi        
        cmp edi, 9 ;after 9 passes goes to outer loop
        je outer

    compare:
        mov eax, [aa + edi * 4h] ;higher indexed one
        mov ebx, [aa + edi * 4h - 4h] 

;testing        print chr$(13,10)
;testing        print str$(eax)
;testing        print chr$(13, 10)
;testing        print str$(ebx)
;testing        print chr$(13, 10)

        cmp ebx, eax
        jg swap

    swap:
        mov [aa + edi * 4h], eax
        mov [aa + edi * 4h + 4], ebx
        jmp inner

end_loop:

    ;print out array elements
    sub esi, esi
    mov esi, [aa]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 2]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 3]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 4]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 5]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 6]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 7]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 8]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 9]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

exit


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start                       ; Tell MASM where the program ends

一个明显的问题就在这里:

    cmp ebx, eax
    jg swap

swap:
    mov [aa + edi * 4h], eax
    mov [aa + edi * 4h + 4], ebx
    jmp inner
在这种情况下,如果设置了
g
标志,它将跳转到swap,但是如果未设置
g
标志,它将跳转到swap,因此它以两种方式执行完全相同的代码。猜测一下,如果两个项目已经安排好了,您可能希望像
jle internal
这样跳过交换

编辑:再看一遍,你似乎有另一个相当明显的问题。让我们用类似于C的东西来思考,并使用
base
作为从何处加载
eax
(在
compare
)的地址。你(概念上)做:

然后在
交换时执行以下操作:

*base = eax;
*(base - 4) = ebx;
这显然也是错误的。要交换这两个变量,您需要如下内容:

*base = ebx;
*(base + 4) = eax;

找出了问题所在——程序中间的打印语句是在影响我的记忆力。这是工作票。谢谢大家的帮助

    .data
          aa DWORD 10 DUP(5, 7, 6, 1, 4, 3, 9, 2, 10, 8)
        count DWORD -1
; DB 8-bits, DW 16-bit, DWORD 32, WORD 16 BYTE 8



    .code                       ; Tell MASM where the code starts

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

start:                          ; The CODE entry point to the program

    mov esi, count ;loop count

    outer:
        inc esi
        mov edi, count        
        cmp esi, 10       
        je end_loop

    inner: ;this loop represents a full pass on the entire array
        inc edi        
        cmp edi, 9 ;after 9 passes goes to outer loop
        je outer

    compare:
        mov eax, [aa + edi * 4h]
        mov ebx, [aa + edi * 4h + 4] ;want to make this one the higher indexed-one

        ;print chr$(13,10) These print calls were hosing the memory before.
        ;print str$(eax)
        ;print chr$(13, 10)
        ;print str$(ebx)
        ;print chr$(13, 10)

        cmp eax, ebx
        jle inner

    swap:
        mov [aa + edi * 4h], ebx
        mov [aa + edi * 4h + 4], eax
        jmp inner

end_loop:

    ;print out array elements
    sub esi, esi
    mov esi, [aa]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 2]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 3]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 4]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 5]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 6]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 7]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 8]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 9]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

exit


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start                       ; Tell MASM where the program ends

谢谢我马上换。然而,我仍然不知道为什么当我打印出EAX时,它总是2。。(在比较函数中,在;测试注释中进行注释)@grey:我不确定。我猜这是一个缩放问题,但我能确定的唯一方法是在调试器下运行它。这就是为什么使用调试器而不是调试打印函数调用或宏!这实际上是一个非常干净/理智的冒泡排序,没有任何愚蠢的东西,比如带有内存的慢速
xchg
(隐式
lock
prefix),或者,或其他浪费的指令。此外,分支/循环结构非常干净。进入
交换:
与一个执行的分支相比,跳过
交换
存储,在底部放置一个
cmp/jne内部
可能或多或少是收支平衡的。但是,从
计数
加载
-1
非常难看,而且对元素的数量进行硬编码也是如此。从内存加载初始
计数
,但硬编码
10
没有意义。:/将外部循环构造为一个
do{}while()
,循环条件位于底部会更干净。此外,最后的打印内容肯定是一个循环,但至少它在排序之后,所以答案是可读的。
    .data
          aa DWORD 10 DUP(5, 7, 6, 1, 4, 3, 9, 2, 10, 8)
        count DWORD -1
; DB 8-bits, DW 16-bit, DWORD 32, WORD 16 BYTE 8



    .code                       ; Tell MASM where the code starts

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

start:                          ; The CODE entry point to the program

    mov esi, count ;loop count

    outer:
        inc esi
        mov edi, count        
        cmp esi, 10       
        je end_loop

    inner: ;this loop represents a full pass on the entire array
        inc edi        
        cmp edi, 9 ;after 9 passes goes to outer loop
        je outer

    compare:
        mov eax, [aa + edi * 4h]
        mov ebx, [aa + edi * 4h + 4] ;want to make this one the higher indexed-one

        ;print chr$(13,10) These print calls were hosing the memory before.
        ;print str$(eax)
        ;print chr$(13, 10)
        ;print str$(ebx)
        ;print chr$(13, 10)

        cmp eax, ebx
        jle inner

    swap:
        mov [aa + edi * 4h], ebx
        mov [aa + edi * 4h + 4], eax
        jmp inner

end_loop:

    ;print out array elements
    sub esi, esi
    mov esi, [aa]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 2]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 3]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 4]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 5]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 6]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 7]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 8]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

    mov esi, [aa + 4h * 9]
    print str$(esi)
    print chr$(" ")
    sub esi, esi

exit


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start                       ; Tell MASM where the program ends