我最近为 arm 目标编写了 c 应用程序。为了交叉编译 arm 目标的应用程序,必须使用一个标志 -mfloat-abi=hard
。但其实我没看懂是什么意思。有人可以解释一下标志的含义吗?编译应用时会有哪些变化?
最佳答案
区别在于调用约定。 ARM 使用基于寄存器的调用约定,其中函数的参数(达到一个限制,之后它们开始溢出到堆栈)和返回值都在寄存器中传递(有关完整的详细信息,请参阅Procedure Call Standard)。当谈到浮点值时,硬件 FPU 协处理器的存在与否引发了一个关于如何处理浮点值的小难题,在生成代码时给出了两种可能性:
Hard-float:您假设浮点硬件存在,并且 FP 参数和返回值在 FPU 寄存器中传递。当您确实有一个 FPU 时,它会更高效,但不能移植到没有 FPU 的机器上,在机器上,代码会在尝试访问不存在的寄存器时崩溃。
Soft-float:浮点参数在通用寄存器中的传递方式与 32 位或 64 位整数的传递方式相同。如果有硬件支持,被调用者函数然后可以将它们传输到 FPU 寄存器中以完成其工作,如果没有硬件支持,则返回到浮点仿真。因此,您的代码可以在任何地方使用正确的库支持,即使在真正的 FPU 硬件上也会有轻微的开销(这对于琐碎的函数可能变得更重要)。
由此,您可能可以推断出您不能将两者混合的原因 - 假设您可以将函数调用编译为 soft-float,但链接到实现该函数的 hard-float 库 -您的调用代码可能会在 r1
中放置一个浮点参数, 但被调用方代码将在 s0
中查找它并继续计算其中包含的任何垃圾值的废话。同样,库函数随后会在 s0
中返回一个 float 结果。 ,但是您的代码会随着 r0
中发生的任何事情而运行。甚至更错。
因此,如果您的工具链提供 hard-float 库,则只有在将代码编译为 hard-float 时才能链接到它们,反之亦然。请注意,multilib 的魔力意味着单个工具链可能同时支持这两种工具,方法是拥有每个库的两个版本并在您链接时自动选择正确的版本。
关于c - 关于为 arm 目标编译应用程序时使用的浮点 abi 标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31500570/