内联汇编乘法“未定义引用";在输入上 [英] Inline assembly multiplication "undefined reference" on inputs

查看:51
本文介绍了内联汇编乘法“未定义引用";在输入上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用内联汇编将400乘以2,使用事实 imul 隐式乘以 eax .但是,我收到未定义的引用",将编译错误编译为 $ 1 $ 2

Trying to multiply 400 by 2 with inline assembly, using the fact imul implicity multiplies by eax. However, i'm getting "undefined reference" compile errors to $1 and $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;

推荐答案

请勿在内联asm中使用固定寄存器,尤其是如果您尚未将其列为Clobbers,并且未确保输入或输出不与它们重叠.(这部分基本上是使用内联汇编时分段错误(核心转储)错误的副本)

Do not use fixed registers in inline asm, especially if you have not listed them as clobbers and have not made sure inputs or outputs don't overlap them. (This part is basically a duplicate of segmentation fault(core dumped) error while using inline assembly)

请勿在内联汇编中切换语法,因为编译器将替换错误的语法.如果要使用intel语法,请使用 -masm = intel .

Do not switch syntax in inline assembly as the compiler will substitute wrong syntax. Use -masm=intel if you want intel syntax.

要引用asm模板字符串中的参数,请使用而不是 $ 前缀. $ 1 没什么特别的;就像您使用 my_extern_int_var 一样,它会被视为符号名称.链接时,链接器找不到 $ 1 符号的定义.

To reference arguments in an asm template string use % not $ prefix. There's nothing special about $1; it gets treated as a symbol name just like if you'd used my_extern_int_var. When linking, the linker doesn't find a definition for a $1 symbol.

不要不必要地 mov 东西.还要记住,仅仅因为某些事情似乎可以在特定的环境中工作,就不能保证它是正确的,并且每次都可以在任何地方工作.对于内联汇编无疑如此.你必须要小心.无论如何,固定版本可能看起来像:

Do not mov stuff around unnecessarily. Also remember that just because something seems to work in a certain environment, that doesn't guarantee it's correct and will work everywhere every time. Doubly so for inline asm. You have to be careful. Anyway, a fixed version could look like:

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

必须使用 -masm = intel 进行编译.注意, b 已与 c 放在同一寄存器中.

Has to be compiled using -masm=intel. Notice b has been put into the same register as c.

使用事实脉冲隐式乘以eax

using the fact imul implicity multiplies by eax

对于正常的2操作数形式的imul 并非如此.它与其他指令的工作方式相同,执行 dst * = src ,因此您可以使用任何寄存器,并且即使您不希望在任何地方写高半字节也不会浪费时间.

That's not true for the normal 2-operand form of imul. It works the same as other instructions, doing dst *= src so you can use any register, and not waste uops writing the high half anywhere if you don't even want it.

这篇关于内联汇编乘法“未定义引用";在输入上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆