简体   繁体   English

GCC 内联汇编中的 0..9 约束有什么作用?

[英]What does the 0..9 constraint do in GCC Inline Assembly?

The manual says:手册说:

"An operand that matches the specified operand number is allowed. If a digit is used together with letters within the same alternative, the digit should come last." “允许使用与指定操作数编号匹配的操作数。如果在同一替代项中将数字与字母一起使用,则该数字应位于最后。”

I'm not sure what this means.我不确定这意味着什么。

Example code:示例代码:

asm volatile("swap %0" : "=r" (value) : "0" (value));

It's like a way to split up a "+r"(value) input/output operand into separate operands (with separate C variables) for input and output while still forcing them to pick the same register.这就像一种将"+r"(value)输入/输出操作数拆分为单独的操作数(具有单独的 C 变量)用于输入和输出的方法,同时仍然强制它们选择相同的寄存器。

Specifically "0" means "input operand in the same register as operand 0", which in this case is "=r"(value) .具体来说, "0"表示“在与操作数 0 相同的寄存器中输入操作数”,在本例中为"=r"(value) So whatever register %0 picks, %1 will be the same register.所以无论寄存器%0选择什么, %1都是同一个寄存器。 Operands are counted left to right, starting with 0 .操作数从左到右计数,从0开始。 The same numbering of operands for %0 , %1 , etc. in the asm template applies when a matching constraint refers to an earlier operand.当匹配约束引用较早的操作数时,asm 模板中的%0%1等操作数的相同编号适用。

I've only ever seen it used with an input constraint matching an output constraint.我只见过它与匹配输出约束的输入约束一起使用。 This lets you omit it from the template without risk that the compiler is expecting your asm template to copy from one reg to another.这使您可以从模板中省略它,而不会有编译器期望您的 asm 模板从一个 reg 复制到另一个的风险。

Using the same C variable for both input and output is easier with "+r"(value) .使用"+r"(value)更容易为输入和输出使用相同的 C 变量。 Matching constraints for this is pointless complexity.为此匹配约束是毫无意义的复杂性。

Maybe "+r" was only added in a later gcc version because you do see matching constraints used when a read/write operand would be easier.也许"+r"只是在后来的 gcc 版本中才添加的,因为当读/写操作数更容易时,您确实会看到使用的匹配约束。

If a digit is used together with letters within the same alternative, the digit should come last."如果一个数字与同一替代中的字母一起使用,则该数字应排在最后。”

This is considering the possibility of a constraint that gives the compiler a choice of multiple constraints.这是考虑给编译器选择多个约束的约束的可能性。 eg "rm" lets the compiler choose register or memory.例如"rm"让编译器选择寄存器或内存。

"a0" on x86 would choose either EAX or the same register as operand 0 . x86 上的"a0"将选择 EAX 或与操作数0相同的寄存器。 I'm not sure when that would be useful.我不确定那什么时候有用。 Maybe it can be used with an early-clobber to tell the compiler that it's still ok for this input to be in the same register as a certain output?也许它可以与早期的clobber一起使用来告诉编译器这个输入与某个输出在同一个寄存器中仍然可以? But optionally any register, like with "r0" ?但是可以选择任何寄存器,比如"r0"

Obviously if you use a constraint like "r0" you (normally) need to explicitly use %1 (or whatever number or named operand it has) in the asm template since you don't know which location the compiler will pick given the surrounding code and optimization levels.显然,如果您使用像"r0"这样的约束,您(通常)需要在 asm 模板中显式使用%1 (或它具有的任何数字或命名操作数),因为您不知道编译器会在给定周围代码的情况下选择哪个位置和优化级别。


When debugging constraints, it can be useful to use an asm comment that includes the constraints , including ones you're going to make assumptions about.在调试约束时,使用包含约束的 asm 注释会很有用,包括您要对其进行假设的那些。

asm ("swap %0    # other operand: %1  "  : "=r"(output) : "0"(input));

The resulting asm will print the same register name twice, for both %0 and %1 .生成的 asm 将为%0%1打印两次相同的寄存器名称。 This case is trivial;这种情况是微不足道的; it gets more interesting in more complicated cases.在更复杂的情况下它会变得更有趣。

Like if you'd used "r"(input) , your code might happen to work because the compiler did pick the same reg for input and output (because no early-clobber).就像您使用了"r"(input)一样,您的代码可能会正常工作,因为编译器确实为输入和输出选择了相同的 reg(因为没有 early-clobber)。 But then when it breaks because it picks a different reg for output (and expects the original value of input to still be in its register unchanged), you can debug it by looking at what regs the constraints picked and then realizing you were assuming they'd pick the same reg but didn't tell the compiler about it.但是当它因为选择了不同的 reg 作为output而中断时(并且期望input的原始值仍然在其寄存器中不变),您可以通过查看选择的约束条件然后意识到您假设它们来调试它d 选择相同的 reg,但没有告诉编译器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM