在 C 中嵌入汇编,编译器为您查找寄存器

发布于 2024-07-21 12:31:45 字数 148 浏览 8 评论 0原文

将汇编代码嵌入到 C/C++ 程序中时,可以通过使用推送指令保存寄存器(或指定支持它的编译器的破坏列表)来避免破坏寄存器。

如果您包含内联汇编并且希望避免推送和弹出损坏的寄存器的开销,有没有办法让 gcc 为您选择寄存器(例如,它知道其中没有有用信息的寄存器)。

When embedding assembly code into a C/C++ program, you can avoid clobbering registers by saving them with a push instruction (or specify clobber list of compiler supports it).

If you are including assembly inline and want to avoid the overhead of pushing and popping clobbered registers, is there a way of letting gcc choose registers for you (e.g. ones it knows have no useful info in them).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一个人的旅程 2024-07-28 12:31:45

好的,所以我不能在上面留下评论,但我很确定正确的语法(与上面显示的不同)是:

asm ( "your assembly instructions"
    : "=a"(output1),
      "=r"(output2),
      "=q"(output3),
      "=A"(output4)
    : /* inputs */
    : /* clobbered registers */
);

虽然你可以将输入和输出寄存器的分配留给编译器,但没有明显的方法将暂存/临时寄存器的分配(即用于中间值而不是输入或输出)留给编译器。 从历史上看,我只是将它们显式地列在 clobber 列表中(例如“%xmm1”、“%rcx”),但我现在认为最好将它们列为输出,以便允许编译器选择它们。 我不知道有任何消息来源可以明确解决这个问题。

OK, so I can't leave a comment above, but I'm pretty sure that the correct syntax (different from that shown above) is:

asm ( "your assembly instructions"
    : "=a"(output1),
      "=r"(output2),
      "=q"(output3),
      "=A"(output4)
    : /* inputs */
    : /* clobbered registers */
);

Although you can leave the allocation of input and output registers to the compiler, there's no obvious way of leaving the allocation of scratch/temp registers (i.e. used for intermediate values but not an input or output) to the compiler. Historically, I just listed them explicitly in the clobber list (e.g. "%xmm1", "%rcx"), but I now think it might be better to list them as outputs in order to allow the compiler to choose them. I don't know of any source that addresses this issue definitively.

旧人 2024-07-28 12:31:45

编译器内部函数是混合汇编和C/C++ 代码。 它们是看起来像函数的声明,但实际上直接编译为单独的本机指令(通过编译器内的特殊情况)。 这为您提供了对汇编工作的大部分控制,但将寄存器着色和调度留给编译器。

一个优点是,您可以将普通的 C 变量传递到内在函数中,并让编译器负责将其加载到寄存器并围绕它调度其他操作。 例如,

struct TwoVectors
{
   __m128 a; __m128b;
}

// adds two vectors A += B using the native SSE opcode
inline void SimdADD( TwoVectors *v ) 
{
   v->a = _mm_add_ps( v->a , v->b ); // compiles directly to ADDSS opcode
}

Compiler intrinsics are a very useful way to mix assembly and C/C++ code. They're declarations that look like functions, but actually compile directly to individual native instructions (via a special case inside the compiler). This gives you much of the control of working in assembly, but leaves the register coloring and scheduling up to the compiler.

An advantage is that then you can pass an ordinary C variable into an intrinsic, and let the compiler take care of loading it onto the register and scheduling other ops around it. For example,

struct TwoVectors
{
   __m128 a; __m128b;
}

// adds two vectors A += B using the native SSE opcode
inline void SimdADD( TwoVectors *v ) 
{
   v->a = _mm_add_ps( v->a , v->b ); // compiles directly to ADDSS opcode
}
绝影如岚 2024-07-28 12:31:45

是的。 您可以指定希望将特定变量(输入或输出)存储在寄存器中,但不必指定寄存器。 有关详细说明,请参阅本文档。 本质上,内联汇编看起来像这样:

asm("your assembly instructions"
      : output1("=a"),  // I want output1 in the eax register
        output2("=r"),  // output2 can be in any general-purpose register
        output3("=q"),  // output3 can be in eax, ebx, ecx, or edx
        output4("=A")   // output4 can be in eax or edx
      : /* inputs */
      : /* clobbered registers */
   );

Yes. You can specify that you want a particular variable (input or output) to be stored in a register, but you don't have to specify a register. See this document for a detailed explanation. Essentially, the inline assembly looks like this:

asm("your assembly instructions"
      : output1("=a"),  // I want output1 in the eax register
        output2("=r"),  // output2 can be in any general-purpose register
        output3("=q"),  // output3 can be in eax, ebx, ecx, or edx
        output4("=A")   // output4 can be in eax or edx
      : /* inputs */
      : /* clobbered registers */
   );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文