输入的内联汇编乘法 "undefined reference"

Inline assembly multiplication "undefined reference" on inputs

尝试使用内联汇编将 400 乘以 2,使用事实 imul 隐式乘以 eax。但是,我收到 "undefined reference" 编译错误到 </code> 和 <code>

 int c;
 int a = 400;
 int b = 2;

 __asm__(
  ".intel_syntax;"
  "mov eax, ;"
  "mov ebx, ;"
  "imul %0, ebx;"
  ".att_syntax;"
  : "=r"(c)
  : "r" (a), "r" (b)
  : "eax");

std::cout << c << std::endl;

不要在内联 asm 中使用固定寄存器,特别是如果您没有将它们列为破坏者并且没有确保输入或输出不与它们重叠。 (这部分基本上是的翻版)

不要在内联汇编中切换语法,因为编译器会替换错误的语法。如果需要英特尔语法,请使用 -masm=intel

要在 asm 模板字符串中引用参数,请使用 % 而不是 $ 前缀。 </code> 没有什么特别之处;它被视为符号名称,就像您使用 <code>my_extern_int_var 一样。链接时,链接器找不到 </code> 符号的定义。</p> <p>不要<code>mov 不必要的东西。还要记住,仅仅因为某些东西似乎在特定环境中工作,并不能保证它是正确的并且每次都能在任何地方工作。内联汇编更是如此。你必须要小心。无论如何,固定版本可能如下所示:

__asm__(
  "imul %0, %1"
  : "=r"(c)
  : "r" (a), "0" (b)
  : );

必须使用 -masm=intel 进行编译。注意 b 已放入与 c 相同的寄存器中。


using the fact imul implicity multiplies by eax

the normal 2-operand form of imul 并非如此。它的工作原理与其他指令相同,执行 dst *= src 因此您可以使用任何寄存器,如果您甚至不需要它,也不会浪费 uops 将高半部分写入任何地方。