使用汇编排序后如何刷新 C 数组

发布于 2024-12-04 22:50:36 字数 752 浏览 4 评论 0原文

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

I have been working on a program that will do a bubble sort for n integers. I have hit a wall, as I do not know to refresh the array once my assembler operation are done. Any suggestions would be great.

#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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

后来的我们 2024-12-11 22:50:36

没有什么可以“刷新”的。您的代码运行。 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

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

There's nothing to "refresh". Your code runs. ebx contains input and that's that. (Hint: Your C code also gets transformed into assembly. Looking at what your compiler generates through a disassembler might give you some insight.)

That said I see some problems:

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

This allocation is not big enough and your program will crash. You want to allocate sizeof(int) * n. You should also check the allocation for errors.

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

Kind of verbose. You should be able to do register-to-memory comparisons. (eg. cmp al, byte [ebx + edi])

Not to mention it's a complete waste of time to implement bubble sort in assembly. Rephrase: Learning assembly is great, but it would be a bad idea to use this in anything that matters. One of the most important things about knowing assembly is knowing when you don't need to use it. You'd probably find very often that what your compiler generates is good enough. Let's also not forget that a good algorithm in C will beat a bad algorithm in assembly, such as bubble sort.

@Giorgio also raises a good point in the comments. Your assembly is comparing and sorting bytes. You want to be doing things like this:

mov eax, [ebx + edi - 4]    ; assumes edi is a byte offset, see next comment
mov edx, [ebx + edi]

And instead of dec edi etc., you want to do:

sub edi, 4

Your swap would also have to be re-done to use 32-bit quantities.

This is of course assuming int is 32 bits, which may not be the case. If you're using (non-standard) inline assembly it's probably fair that you're doing this - it means you're already targeting a particular compiler. (Based on the syntax I'd say VC++) Nitpickers might say you should use int32_t instead of int.

Note I'm not sure if this is the only problem, I haven't looked at your code too thoroughly.

累赘 2024-12-11 22:50:36

我也会尝试一下。

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

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

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

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

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

    __asm
    {
        mov ecx, s
        mov ebx, input
        mov esi, n
        mul esi, ecx

    outer_loop:
        sub esi, ecx
        jz end_outer
        mov edi, esi

    inner_loop:
        sub edi, ecx
        jz outer_loop

    compare:
        mov edx, [ebx + edi]
        sub edi, ecx
        mov eax, [ebx + edi]
        add edi, ecx

        cmp eax, edx
    jnl inner_loop

    swap:
        mov [ebx + edi], eax
        sub edi, ecx
        mov [ebx + edi], edx
        add edi, ecx
        jmp inner_loop

    end_outer:
    }

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

    scanf("%d", &output);
}

我使用变量 s 来保存整数的大小。据我所知,不允许使用像这样的间接寻址,

mov eax, [ebx + edi + ecx]

因此我必须添加单独的 add 和 sub 。这不是很好,有人看到更好的解决方案吗?

I will also give it a try.

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

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

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

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

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

    __asm
    {
        mov ecx, s
        mov ebx, input
        mov esi, n
        mul esi, ecx

    outer_loop:
        sub esi, ecx
        jz end_outer
        mov edi, esi

    inner_loop:
        sub edi, ecx
        jz outer_loop

    compare:
        mov edx, [ebx + edi]
        sub edi, ecx
        mov eax, [ebx + edi]
        add edi, ecx

        cmp eax, edx
    jnl inner_loop

    swap:
        mov [ebx + edi], eax
        sub edi, ecx
        mov [ebx + edi], edx
        add edi, ecx
        jmp inner_loop

    end_outer:
    }

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

    scanf("%d", &output);
}

I used variable s to hold the size of an integer. To my knowledge it is not allowed to use an indirection like

mov eax, [ebx + edi + ecx]

therefore I had to add separate add and sub. It is not very nice, does anyone see a better solution?

紫南 2024-12-11 22:50:36

您似乎打算分配并输入一个由 n int 值组成的数组。 (尽管 malloc 中的内存大小不正确,正如已经指出的那样)。

但随后您继续将数组排序为 n 字节 数组。为什么要对字节进行排序而不是对 int 进行排序?

即使您的排序算法正确实现(作为字节排序实现),最终结果看起来也完全没有意义,因为您最终将数组打印为 int 数组。

首先确定您要使用的是什么:int 或字节(char),然后采取一致的相应行动。

You seem to intend to allocate and input an array of n int values. (Although the memory size in your malloc is incorrect, as has already been noted).

But then you proceed to sort your array as an array of n bytes. Why are you sorting bytes instead of sorting ints?

Even if your sorting algorithm is implemented correctly (as byte-sorting implementation), the end result will look totally meaningless, since you are printing your array as an array of ints in the end.

First make up your mind what is that you are trying to work with: ints or bytes (chars) and then act accordingly and consistently.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文