Gcc GNU程序集内联:%1和%0是什么意思?

Gcc GNU程序集内联:%1和%0是什么意思?,gcc,assembly,x86,inline-assembly,att,Gcc,Assembly,X86,Inline Assembly,Att,我对GNU汇编内联非常陌生,我读过多篇文章,但仍然不完全理解正在发生的事情。据我了解: movl%eax,%ebx\n\t会将%eax中的任何内容移动到ebx,但不会将内容添加到彼此中 addl%eax,%ebx\n\t将使用ebx添加%eax的内容,并将其保留在最右边的寄存器中 添加%1,%0\n\t这就是我感到困惑的地方,我们正在添加1和0?为什么我们需要将%0放在那里?整个asm内联块看起来像: asm [volatile] ( AssemblerTemplate

我对GNU汇编内联非常陌生,我读过多篇文章,但仍然不完全理解正在发生的事情。据我了解:

movl%eax,%ebx\n\t
会将
%eax
中的任何内容移动到
ebx
,但不会将内容添加到彼此中

addl%eax,%ebx\n\t
将使用
ebx
添加
%eax
的内容,并将其保留在最右边的寄存器中


添加%1,%0\n\t
这就是我感到困惑的地方,我们正在添加1和0?为什么我们需要将
%0
放在那里?

整个asm内联块看起来像:

 asm [volatile] ( AssemblerTemplate
                      : OutputOperands
                      [ : InputOperands
                      [ : Clobbers ] ])

在AssemblerTemplate中是您的汇编代码,在Output/InputOperatorAnds中,您可以在C和ASM之间传递变量

然后在Asm中,%0引用作为OutputOperand或InputOperand传递的第一个变量,%1到第二个变量,以此类推

例如:

 int32_t a = 10;
 int32_t b;
 asm volatile ("movl %1, %0" : "=r"(b) : "r"(a) : );
此asm代码相当于“b=a;”


更详细的解释如下:

整个asm内联块如下所示:

 asm [volatile] ( AssemblerTemplate
                      : OutputOperands
                      [ : InputOperands
                      [ : Clobbers ] ])

在AssemblerTemplate中是您的汇编代码,在Output/InputOperatorAnds中,您可以在C和ASM之间传递变量

然后在Asm中,%0引用作为OutputOperand或InputOperand传递的第一个变量,%1到第二个变量,以此类推

例如:

 int32_t a = 10;
 int32_t b;
 asm volatile ("movl %1, %0" : "=r"(b) : "r"(a) : );
此asm代码相当于“b=a;”


这里有更详细的解释:

在at&t语法中,目标是右侧,因此“将其保留在最左侧寄存器”是错误的。%0和%1引用约束部分中列出的替换输入/输出操作数。你可能想读一下。@Jester抱歉是个打字错误,这就是我的意思。现在有道理了,如果我使用%2,那将是第三个输入/输出操作数?是的。另请注意,您可以使用
%[name]
形式的命名操作数,以使代码更具可读性。您可以始终查看编译器输出,以确保以预期的方式替换%number占位符。如果使用内联asm,请确保在关闭标记(条件condes)时告诉编译器,关闭器列表中有一个“cc”条目。如果您在asm中编写独立函数并从C调用它们,学习asm会更容易。(将原型放在
.h
main.C
中,但只在
.s
文件中定义函数。)。gcc内联asm比普通asm更难读取/使用。尽可能使用内置函数(例如popcnt或SSE)。第一个建议:“权威”语法在中。本文提供了一个更好的解释和教程,包括真实的例子、陷阱和正确的用法@彼得科德斯的建议非常好。添加一些内联asm,使用
-c-S
编译,并查看程序集输出。对于简单的内联(扩展)asm,您可能还不知道ABI就可以离开。在at&t语法中,目标是右侧,因此“将其保留在最左侧寄存器”是错误的。%0和%1引用约束部分中列出的替换输入/输出操作数。你可能想读一下。@Jester抱歉是个打字错误,这就是我的意思。现在有道理了,如果我使用%2,那将是第三个输入/输出操作数?是的。另请注意,您可以使用
%[name]
形式的命名操作数,以使代码更具可读性。您可以始终查看编译器输出,以确保以预期的方式替换%number占位符。如果使用内联asm,请确保在关闭标记(条件condes)时告诉编译器,关闭器列表中有一个“cc”条目。如果您在asm中编写独立函数并从C调用它们,学习asm会更容易。(将原型放在
.h
main.C
中,但只在
.s
文件中定义函数。)。gcc内联asm比普通asm更难读取/使用。尽可能使用内置函数(例如popcnt或SSE)。第一个建议:“权威”语法在中。本文提供了一个更好的解释和教程,包括真实的例子、陷阱和正确的用法@彼得科德斯的建议非常好。添加一些内联asm,使用
-c-S
编译,并查看程序集输出。对于简单的内联(扩展)asm,您可能还不知道ABI就可以离开。