我们知道,如果我将 %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 相同的寄存器。
关于我可以修改gcc内联汇编中的输入操作数吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48381184/