如何在使用程序集进行排序后刷新C数组

Rya*_*yan 1 c arrays assembly bubble-sort

我一直在研究一个程序,它将对n个整数进行冒泡排序.我已经撞墙,因为我不知道在我的汇编程序操作完成后刷新数组.任何建议都会很棒.

#include <stdio.h>
#include <stdlib.h>

int n;
int *input;
int output;
int i;

int main(void)
{
scanf("%d", &n);

input = (int *)malloc(sizeof(n));

for (i = 0; i < n; i++)
{
    scanf("%d", &input[i]);
}

__asm
{
    mov ebx, input
    mov esi, n


outer_loop:
    dec esi
    jz end_outer
    mov edi, n

inner_loop:
    dec edi
    jz outer_loop

compare:
    mov al, [ebx + edi - 1]
    mov dl, [ebx + edi]
    cmp al, dl
    jnl inner_loop

swap:
    mov [ebx + edi], al
    mov [ ebx + edi - 1], dl
    jmp inner_loop

end_outer:



}

for (i = 0; i < n; i++)
{
    printf("%d\n", input[i]);
}
scanf("%d", &output);
}
Run Code Online (Sandbox Code Playgroud)

asv*_*kau 6

没有什么可以"刷新".你的代码运行. ebx包含input那就是那个.(提示:您的C代码也会转换为汇编.查看编译器通过反汇编程序生成的内容可能会给您一些见解.)

那说我看到了一些问题:

input = (int *)malloc(sizeof(n));
Run Code Online (Sandbox Code Playgroud)

这个分配不够大,你的程序会崩溃.你想分配sizeof(int) * n.您还应该检查错误分配.

mov al, [ebx + edi - 1]
mov dl, [ebx + edi]
cmp al, dl
Run Code Online (Sandbox Code Playgroud)

有点冗长.您应该能够进行寄存器到内存的比较.(例如cmp al, byte [ebx + edi])

更不用说在装配中实现冒泡排序完全浪费时间了.改写:学习集会很棒,但在任何重要事项中使用它都是一个坏主意.了解装配最重要的事情之一就是知道什么时候不需要使用它.您可能经常发现编译器生成的内容足够好.让我们也不要忘记C中的一个好算法会击败汇编中的错误算法,例如冒泡排序.

@Giorgio也在评论中提出了一个很好的观点.您的程序集正在比较和排序字节.你想做这样的事情:

mov eax, [ebx + edi - 4]    ; assumes edi is a byte offset, see next comment
mov edx, [ebx + edi]
Run Code Online (Sandbox Code Playgroud)

而不是dec edi等,你想做:

sub edi, 4
Run Code Online (Sandbox Code Playgroud)

您还必须重新进行交换才能使用32位数量.

这当然假设int是32位,可能不是这种情况.如果您正在使用(非标准)内联汇编,那么您执行此操作可能是公平的 - 这意味着您已经针对特定的编译器.(基于语法我会说VC++)Nitpickers可能会说你应该用int32_t而不是int.

注意我不确定这是否是唯一的问题,我没有仔细查看你的代码.