Asy*_*ode 4 c gcc inline-assembly
我们知道,如果我设置%eax为输入,那么我无法将其包含到破坏寄存器列表中。所以我的问题是,修改%eax汇编代码中的值而不在破坏列表中进行任何声明是否合法?
__asm__ __volatile__("inc %0" :: "a"(num) : "%eax"); // illegal
__asm__ __volatile__("inc %0" :: "a"(num)); // Can I modify %eax?
Run Code Online (Sandbox Code Playgroud)
不可以,如果汇编代码更改了输入寄存器,则还必须通过在约束中使用“+”而不是“=”将其列为输出寄存器或输入输出寄存器。
例子:
__asm__ __volatile__("..." : "+r"(num));
__asm__ __volatile__("..." : "=a"(dummy) : "a"(num));
__asm__ __volatile__("..." : "=r"(dummy) : "0"(num));
Run Code Online (Sandbox Code Playgroud)
第一个示例指定num为输入和输出。这将覆盖 的先前值num,如果操作数被破坏而不是被设置为有用的值,则这可能是不可取的。
第二个示例明确使用 eax 作为输入和输出。它将输出定向到dummy变量,以免破坏实际的输入变量num。
第三个示例使用虚拟输出,以避免修改num,并且还避免显式指定 eax,从而允许编译器选择要使用的寄存器。该"0"约束告诉编译器为此输入操作数使用与操作数 0 相同的寄存器。