Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 什么';我的组装气泡排序有什么问题吗?_Assembly_X86_Masm_Bubble Sort - Fatal编程技术网

Assembly 什么';我的组装气泡排序有什么问题吗?

Assembly 什么';我的组装气泡排序有什么问题吗?,assembly,x86,masm,bubble-sort,Assembly,X86,Masm,Bubble Sort,我正在使用基本伪代码/大纲在程序集中实现气泡排序: for i in array if array[i] >= array[i+1] exchange array[i], array[i+1] 我的ASM代码: BubbleSort PROC mov EBX, LENGTHOF myArr .REPEAT mov ESI, 0 mov ECX, LENGTHOF myArr .

我正在使用基本伪代码/大纲在程序集中实现气泡排序:

for i in array
    if array[i] >= array[i+1]
        exchange array[i], array[i+1]
我的ASM代码:

BubbleSort PROC
    mov     EBX, LENGTHOF myArr
    .REPEAT
        mov     ESI, 0
        mov     ECX, LENGTHOF myArr
        .REPEAT
            mov     EAX, [myArr + ESI]
            .IF EAX >= [myArr + ESI + TYPE myArr]       ; If (myArr[i] < myArr[i + 1])
                xchg    EAX, [myArr + ESI + TYPE myArr]
                mov     [myArr + ESI], EAX
            .ENDIF

            add     ESI, TYPE myArr
            dec     ECX
        .UNTIL ECX == 0
    dec     EBX
    .UNTIL EBX == 0
    ret
BubbleSort ENDP
BubbleSort程序
mov EBX,myArr的长度
.重复
电影ESI,0
mov ECX,myArr的长度
.重复
mov EAX,[myArr+ESI]
。如果EAX>=[myArr+ESI+类型myArr];If(myArr[i]
当我向我的教授展示我的实现时,他说这是“有点”像冒泡排序或“类型”冒泡排序。在告诉我们任务时,他说我们应该从阵列的后面开始,然后从后面移到前面。然而,我从前面开始,前后移动

我觉得我在正确的轨道上,代码可以正常工作,但我想正确地完成它


有人看到我把事情搞砸了吗?

假设你的代码可以工作,那肯定是冒泡式的。向数组的任一端冒泡是可以的,因此不进行优化,例如使用外循环计数器(
EBX
)作为内循环的上限

简单化或天真并不能阻止它成为泡泡式的。(如果说有什么区别的话,那就是过于简单和幼稚才是泡沫式的关键。)


有关冒泡排序历史的更多信息,请参见,并讨论相关的跳转排序,以及是否使用布尔值作为早期输出

它提供的BubbleSort版本运行从
j=n-1
1
(包括)的外部循环,因此内部循环可以将其用作上限。但是内部循环与您的循环相同,从k=0到
j
,有条件地将
A[j]
A[j+1]
交换,从而使元素在数组末尾冒泡

该版本也会向上冒泡,从1运行到
n-1(包括)。Wiki实际上有两个版本:第一个版本和你的一样幼稚,第二个版本在循环中递减
n
。(两个Wiki版本都使用一个布尔变量来记录它是否进行了任何交换,这使算法复杂化,并挫败了冒泡排序的唯一目的/优点,即非常简单,代码也非常小。(例如,尽管它针对大小而非速度进行了大量优化。更正常的实现将类似于InsertionSort的大小。)


您的代码使用的MASM宏最终会浪费指令来重做检查(我假设
。直到ECX==0
都不会利用
dec ECX
已经根据ECX非零设置了标志的事实)。但是它确实有很好的
do{}while()
循环结构,这是asm的惯用结构



顺便说一句,您的伪代码缺少外部循环。这只是BubbleSort的一个过程。但是,是的,迭代
n
次将对
n
元素数组进行排序。

他认为您应该回到前面的原因是什么?如果您查看wikipedia上的纯伪代码实现,它的内部循环是前后循环的,并且它的外循环一直运行,直到不再发生交换。@Michael我不太确定,如果我没记错的话,他说它会比前后循环快。谢谢你提供的信息!我们被告知要使用。重复和。如果在这个练习中不使用cmp。@Small_Kitten:好的,那很好。我的意思是你不需要
cmp
at all.
dec ecx/jnz循环顶部
是在(--ecx)时在
do{}的底部执行的正常操作
loop。隐藏这样的低效率是使用MASM高级构造的一个缺点。一旦你对asm有了更多的经验并了解了标志如何工作,没有它编写循环就很容易了。啊,我现在明白你的意思了,也感谢你!我想我已经在一些示例中看到了这种实现。汇编是非常不同的nt语言比其他语言都好,但到目前为止我很喜欢。@Small_Kitten:酷。如果你想读更多的东西,我在上面写了一个答案。另请参阅文档、手册等的更多链接,以及获取编译器来为你制作示例asm。(一般原则适用于MSVC和GCC)@Small_Kitten:顺便说一句,经常有人问关于堆栈溢出上的asm的家庭作业问题,他们要么讨厌它,要么完全不知所措(否则他们只需使用调试器单步解决自己的问题).因此,当有人有真正的问题时,这是一个很好的改变。无论如何,C与asm没有什么不同。一旦你了解了asm,你就可以考虑在编写C时CPU可以有效地做些什么,以及你希望代码如何编译。你甚至可以用do{}编写类似于asm的C结构虽然是循环,但通常编译器是好的。