我一直在开发一个程序,该程序将对 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/