我在使用 c 语言的一段代码使用内联汇编 block 对数组进行排序时遇到问题。
我的完整代码是这样的:
#include <stdio.h>
#define n 20
int main()
{
int array[n];
int i;
int swapped;
printf("Enter the elements one by one \n");
for (i = 0; i < n; i++)
{
scanf("%d", &array[i]);
}
printf("Input array elements \n");
for (i = 0; i < n ; i++)
{
printf("%d\n", array[i]);
}
/* Bubble sorting begins */
do
{
swapped = 0;
for (i = 1; i < n; i++)
{
/*
if (array[i] < array [i-1])
{
swapped =1;
int temp = array [i-1];
array [i-1] = array [i];
array[i] = temp;
}
*/
//body of the for loop
//converted to assembly
__asm__ __volatile__("cmp %0, %1;"
"jge DONE;"
"mov eax, %0;"
"mov %0, %1;"
"mov %1, eax;"
"mov %2, 1;"
"DONE: "
: "+r" (array[i]), "+r" (array[i-1]), "=r" (swapped)
: //no input
: "eax", "cc"
);
}
} while (swapped > 0);
printf("Sorted array is...\n");
for (i = 0; i < n; i++)
{
printf("%d\n", array[i]);
}
return 0;
}
由于某种原因, do while 变成了无限循环,但是当我更改 swapped
的修饰符时变量为 "+r" (swapped)
它有效。我查看了这两种情况生成的汇编代码(-save-temp),除了移动 swapped
之外没有注意到任何其他内容。在使用“+r”的情况下变量到寄存器,这是预期的。
为什么我需要使用"+r"
?
最佳答案
如果您使用=
,则意味着它是一个输出,并且必须写入。但是,只有在发生交换时才编写它。编译器将优化您使用的 swapped = 0
,因为它假定汇编器 block 将生成一个新值来覆盖它。这意味着,如果没有交换,编译器将很乐意使用它为 %2
选择的寄存器中的任何垃圾作为 swapped
的新值,并且偶然地,产生了无限循环。
下面是一些代码来说明:
swapped = 0;
/* this is the asm block */
{
/* this is not initialized, because it's declared as output */
int register_for_operand2;
if (array[i] < array[i - 1])
{
/* body here */
register_for_operand2 = 1;
}
/* the compiler generates this code for the output operand */
/* this will copy uninitialized value if the above condition was false */
swapped = register_for_operand2;
}
关于c - GCC x86 内联汇编中的 (+r) 与 (=r) 约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26722008/