【问题标题】:Weird sorting issue with bubble sort using ASM inline assembly (64 bit)使用 ASM 内联汇编(64 位)的冒泡排序的奇怪排序问题
【发布时间】:2015-06-26 17:30:51
【问题描述】:

我目前正在 64 位机器上使用 C 进行内联 ASM 汇编(我认为)。至少对于 gcc,我应该使用 gcc -Wall -masm=intel name.c -o name 进行编译。无论如何,我们必须使用某些规范来实现冒泡排序。

主要是模板应该是这样的:

#include <stdio.h>

#define ARRAY_LENGTH 20

int main()
{
    int array[ARRAY_LENGTH];
    int i;
    int swapped;

    printf("Enter the elements one by one \n");
    for (i = 0; i < ARRAY_LENGTH; i++)
    {
        scanf("%d", &array[i]);
    }

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

    /*  Bubble sorting begins */
    do
    {
        swapped = 0;
        /*
        for (i = 1; i < ARRAY_LENGTH; i++)
        {
            if (array[i] < array [i-1])
            {
                swapped = 1;
                int temp = array [i-1];
                array [i-1] = array [i];
                array[i] = temp;
            }
        }
        */
        __asm__ __volatile__(";"                              //use up to 20 inst.
                             :"+r" (swapped)                  //don't touch this line 
                             :"b" (array), "a" (ARRAY_LENGTH) //don't touch this line
                             :"memory"                        //include other clobbered regs
                             );

    } while (swapped > 0);

    printf("Sorted array is...\n");
    for (i = 0; i < ARRAY_LENGTH; i++)
    {
        printf("%d\n", array[i]);
    }

    return 0;
}

基本上我们应该在汇编中实现 for 循环,以及交换代码。对于交换,我们应该使用异或算法。这是我的汇编代码:

__asm__ __volatile__(   "mov rsi, 0;"
                                "FOR:" // start for loop
                                "add rsi, 1;"   
                                "cmp rsi, rax;" // is rsi > array length (i < length?)
                                "jg END_FOR;" // if so jump to end of for loop
                                // else carry on with for loop, set values for a[i]/a[i-1]
                                "mov ecx, dword ptr [rbx + 4 * rsi];"
                                "mov edx, dword ptr [rbx + 4 * (rsi - 1)];" // set the values to ecx,edx
                                "cmp ecx, edx;" // a[i] > a[i-1]? jmp to done, else
                                "jg DONE;"
                                // swap
                                "xor ecx, edx;"
                                "xor edx, ecx;"
                                "xor ecx, edx;" // swap complete
                                // store values back into memory
                                "mov dword ptr [rbx + 4 * rsi], ecx;" // new ecx
                                "mov dword ptr [rbx + 4 * rsi - 4], edx;" // new edx
                                "mov %0, 1;"
                                "DONE:" // end else // increment counter
                                "jmp FOR;" // jump back to start of for loop
                                "END_FOR:"
                                : "+r" (swapped)        // don't touch this line [output]
                                : "b" (array), "a" (ARRAY_LENGTH) // dont touch this line [input]
                                : "memory", "cc", "rsi", "ecx", "edx"           // include other clobbered reg
                             );

问题是我的代码正在做一些非常奇怪的排序事情。出于某种原因,一组特定的值会给我一个几乎排序的数组。其他时候,程序继续无限循环:|我的老师看了看,不知道出了什么问题,老实说我也不知道。

例如,使用这个输入:

11
-11
12
-12
13
-13
14
-14
15
-15
16
-16
17
-17
18
-18
19
-19
20
-20

产生这个结果:

-20
-19
-18
-17
-16
-15
-14
-13
-12
-11
0
11
12
13
14
15
16
17
18
19

使用此输入时:

100
90
80
70
60
50
40
30
20
10
0
-10
-20
-30
-40
-50
-60
-70
-80
-90

只是继续无限循环:/ 更奇怪的是,我旁边的那个人实际上是从我那里复制过来的,除了使用不同的寄存器来分配他的值,而且他的程序运行正常。有人知道该怎么做吗?

【问题讨论】:

  • 这对我来说运行正确。除了一些轻微的低效率外,我没有发现任何问题。这可能是环保的吗?你使用的是什么版本的 gcc?你是如何运行代码的?也许您应该使用 -o name.exe?
  • 我学校的实验室服务器正在使用 gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11)。而且我在使用 ./bubble_sort 执行 gcc 行之后运行代码
  • OffTopic:不需要 XOR 交换代码。您在寄存器中都有这两个值,只需将它们存储到正确的内存位置即可。
  • OnTopic:jg END_FOR 应该是 jge END_FOR,因为 &lt; 的对面是 &gt;=
  • 是jge :|感谢那!我也问过教授,但他告诉我们我们仍然必须实现异或交换:/

标签: c sorting gcc assembly


【解决方案1】:

jg END_FOR 的行应该是 jge END_FOR,因为 &lt; 的对面是 &gt;= – user3386109

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    相关资源
    最近更新 更多