c - 如何在使用程序集排序后刷新 C 数组

标签 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);
}

最佳答案

没有什么可以“刷新”的。您的代码运行。 ebx 包含 input 就是这样。 (提示:您的 C 代码也会转换为汇编代码。查看您的编译器通过反汇编程序生成的内容可能会让您有所了解。)

也就是说我看到了一些问题:

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

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

mov al, [ebx + edi - 1]
mov dl, [ebx + edi]
cmp al, dl

有点冗长。您应该能够进行寄存器到内存的比较。 (例如 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]

而不是 dec edi 等,你想做的是:

sub edi, 4

您的交换也必须重新进行才能使用 32 位数量。

这当然是假设 int 是 32 位的,实际情况可能并非如此。如果您正在使用(非标准)内联汇编,那么您这样做可能是公平的 - 这意味着您已经针对特定的编译器。 (基于语法,我会说 VC++)吹毛求疵的人可能会说你应该使用 int32_t 而不是 int

请注意,我不确定这是否是唯一的问题,我还没有仔细查看您的代码。

关于c - 如何在使用程序集排序后刷新 C 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7435109/

相关文章:

将 INT_MAX 转换为 float ,然后再转换回整数。

c - 如何在屏幕上显示搜索到的字符串?

java - 如何在类构造函数中定义数组作为参数?

arrays - 在 SAS 中使用数组

c++ - Autotools 提示使用不同上下文编译的文件

c - 所以 setsockopt 用于 AF_UNIX (AF_LOCAL) 套接字超时...未记录/不起作用...选项/替代方案?

python - 如何在 NumPy 中将 2d 数组的值分配给 3d 数组

c - 使堆栈指针指向 mmap 返回的指针。 (Linux,32 位虚拟机)

assembly - AVX-512中的压缩和扩展指令之间有什么区别?

c - 需要帮助理解此函数中的 movzbl 调用