x86(masm32)中的冒泡排序,我编写的排序不';行不通
我正在尝试用x86(masm32)编写一个冒泡排序。这样不行。我已经测试了一些代码,在比较和交换部分,它似乎是一团糟。 出于某种原因,比较函数总是将2分配给EAX。如果我能弄明白为什么我能让程序工作 提前谢谢你的帮助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
.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