c-引用不带约束的内联程序集变量



我想在C程序中使用内联汇编,而不使用约束,因为我不想在我足够复杂的学校论文中解释这一点。我正试图用一个密钥对一些字符进行异或。这是代码:

#include <stdio.h>
char text[11] = {'H','e','l','l','o'};
int key = 42;
int e;
char z;
int main()
{
for (e=0; e<12; e++){
z = text[e];
asm volatile(
"movl $z, %ax;" 
"movl $key, %bx;" 
"xor $ax, %bx;" 
"movl $ax, %[z];");
printf("%cn", z);
}
return 0;
}

但我不断得到:main.c:11:13: error: undefined named operand ‘z’ "movl $key, %ax;" 我尝试在变量前面添加static,因为它可能是编译器/链接器优化的东西。我也尝试添加__attribute__((used)),但都没有帮助。我使用的是GNU GCC v7.1.1感谢您的帮助。

如果可能,请完全避免使用内联程序集。

如果必须使用内联程序集,请尽可能使用扩展内联程序集,并声明正确的操作数和clobber列表。在您的特定情况下,类似这样的东西会起作用:

#include <stdio.h>
char text[11] = {'H','e','l','l','o'};
int key = 42;
int e;
char z;
int main()
{
for (e=0; e<12; e++){
z = text[e];
asm (
"movzbl %0, %%eax;" 
"movl %1, %%ebx;" 
"xor %%ebx, %%eax;" 
"movb %%al, %0;"
: "+m"(z) : "m"(key) : "eax", "ebx");
printf("%cn", z);
}
return 0;
}

这里,"+m"(z)输出操作数,而"m"(key)是输入操作数。"eax", "ebx"clobber列表,指示代码覆盖的寄存器。由于asm语句的所有副作用都是通过其输出操作数和clobber显式的,因此可以省略volatile关键字,从而为编译器提供更大的灵活性。

请注意,除非keyze是全局变量,否则最好将它们转换为自动变量,并对输入和输出操作数使用额外的ri约束,以使编译器在选择将变量保留在何处时具有更大的灵活性。

还要注意校正后的操作数大小。CCD_ 14是一个32位的变量,而CCD_。最后,我为您修复了xor指令。您不小心切换了操作数。

请注意,汇编代码可以做得更好。呈现代码的一种稍微更有效的方法是这样的:

#include <stdio.h>
char text[11] = {'H','e','l','l','o'};
int key = 42;
int e;
char z;
int main()
{
for (e=0; e<12; e++){
z = text[e];
asm (
"xorb %b1, %0"
: "+m"(z) : "r"(key));
printf("%cn", z);
}
return 0;
}

这将从内存加载key委托给C编译器,使其能够在保存变量的位置上做出更明智的选择。将keyz转换为自动变量可能也是一个好主意,但我不确定在某些未命名的约束下是否允许这样做。

最新更新