我可以修改gcc内联汇编中的输入操作数吗

Can I modify input operands in gcc inline assembly

我们知道,如果我将 %eax 设置为输入,那么我无法将其包含在已破坏的寄存器列表中。所以我的问题是,在汇编代码中修改 %eax 的值而不在破坏列表中进行任何声明是否合法?

__asm__ __volatile__("inc %0" :: "a"(num) : "%eax"); // illegal
__asm__ __volatile__("inc %0" :: "a"(num));       // Can I modify %eax?

不可以,如果汇编代码更改了输入寄存器,则还必须将其列为输出寄存器,或列为输入输出寄存器,方法是在约束中使用“+”而不是“=”。

示例:

__asm__ __volatile__("..." : "+r"(num));
__asm__ __volatile__("..." : "=a"(dummy) : "a"(num));
__asm__ __volatile__("..." : "=r"(dummy) : "0"(num));

第一个示例将 num 指定为输入和输出。这将覆盖 num 的先前值,如果操作数被破坏而不是设置为有用的值,这可能是不希望的。

第二个示例明确使用 eax 作为输入和输出。它将输出定向到 dummy 变量,以免破坏实际输入变量 num.

第三个示例使用虚拟输出,以避免修改 num,也避免明确指定 eax,允许编译器选择使用哪个寄存器。 "0" 约束告诉编译器为此输入操作数使用与操作数 0 相同的寄存器。