[英]Inline assembly multiplication "undefined reference" on inputs
尝试使用内联汇编将 400 乘以 2,使用imul
隐式乘以eax
的事实。 但是,我收到$1
和$2
“未定义引用”编译错误
int c;
int a = 400;
int b = 2;
__asm__(
".intel_syntax;"
"mov eax, $1;"
"mov ebx, $2;"
"imul %0, ebx;"
".att_syntax;"
: "=r"(c)
: "r" (a), "r" (b)
: "eax");
std::cout << c << std::endl;
不要在内联汇编中使用固定寄存器,特别是如果您没有将它们列为 clobbers 并且没有确保输入或输出不与它们重叠。 (这部分基本上是使用内联汇编时分段错误(核心转储)错误的重复)
不要在内联汇编中切换语法,因为编译器会替换错误的语法。 如果需要英特尔语法,请使用-masm=intel
。
要引用 asm 模板字符串中的参数,请使用%
而不是$
前缀。 $1
没有什么特别之处; 它被视为符号名称,就像您使用my_extern_int_var
。 链接时,链接器找不到$1
符号的定义。
不要mov
东西周围不必要。 还要记住,仅仅因为某些东西似乎在特定环境中有效,并不能保证它是正确的,并且每次都能在任何地方工作。 内联汇编更是如此。 你必须要小心。 无论如何,固定版本可能如下所示:
__asm__(
"imul %0, %1"
: "=r"(c)
: "r" (a), "0" (b)
: );
必须使用-masm=intel
编译。 注意b
已被放入与c
相同的寄存器中。
使用事实 imul 隐式乘以 eax
对于imul 的正常 2 操作数形式,情况并非如此。 它的工作方式与其他指令相同,执行dst *= src
以便您可以使用任何寄存器,并且如果您甚至不想要它,就不会浪费 uops 在任何地方写入高半部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.