Gcc GNU程序集内联:%1和%0是什么意思?
我对GNU汇编内联非常陌生,我读过多篇文章,但仍然不完全理解正在发生的事情。据我了解: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
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就可以离开。