如果使用C语言编写没有FPU的微处理器,编译器会在遇到浮点文字和关键字时发出错误信号(0.75,浮点数,双精度等)?
此外,如果表达式的结果是小数,会发生什么?
据我所知,有些软件库可以用来进行浮点数学运算,但我特别想知道如果不使用它会得到什么结果。
感谢。
答案 0 :(得分:6)
实现类型float
和double
以及涉及它们的算术表达式需要C实现。因此,如果编译器知道目标体系结构没有浮点运算,那么它必须引入一个软件库来完成它。允许编译器链接到外部库,它也允许在软件中实现浮点操作本身作为内在函数,但它必须以某种方式生成代码才能完成它。
如果它不这样做[*]那么它不是一个符合C的实现,所以严格来说你不是“用C语言编程”。您可以使用编译器文档告诉您的任何内容进行编程。
您希望涉及float
或double
类型的代码将无法编译(因为编译器知道您处于不符合模式并且告诉you)或者无法链接(因为编译器发出对库中的仿真例程的调用,但缺少库)。但就C而言,如果你使用不是C的东西,那就是你自己。
我不知道确切的细节(我看起来多大了?),但是我想,如果您为x87编译了一些代码,那么您可以在系统上链接并加载它一个没有FPU的x86。然后当你试图执行它时,CPU会抱怨非法指令 - 很可能系统会根据你运行的操作系统而挂起。所以最坏的情况非常糟糕。
如果表达式的结果是小数,会发生什么?
表达式的实际结果无关紧要,因为表达式本身要么用整数运算执行(在这种情况下结果不是小数),要么用浮点运算执行(在这种情况下问题出现在你之前)甚至找出结果)。
[*]或者如果你没有指定使它这样做的选项; - )
答案 1 :(得分:4)
根据C标准,浮点是C语言的必需部分。如果目标硬件没有浮点指令,则C实现必须以某种其他方式提供浮点运算,例如通过在软件中模拟它们。 (所有计算只是位的函数。如果你有操作位和执行测试和分支的基本操作,那么你可以计算一般计算机可以执行的任何功能。)
编译器可以提供没有浮点的C子集,但是它不会是符合标准的C编译器。
答案 2 :(得分:2)
软件浮点可以采用两种形式:
编译器可以直接生成对内置浮点函数的调用 - 例如,操作1.2 * 2.5
可以调用(例如)fmul( 1.2, 2.5 )
,
或者对于支持FPU的架构,但某些设备变体可能省略它,通常使用FPU仿真。遇到FP指令时,将发生无效指令异常,并且异常处理程序将转向模拟指令的代码。
FPU仿真的优势在于,当在具有真实FPU的设备上执行相同的代码时,它将自动使用并加速执行。但是,与直接软件实现相比,没有FPU通常会有很小的开销,因此如果预期应用程序永远不会在FPU上运行,则最好避免仿真,因为编译器提供了选项。
软件浮点比硬件支持的浮点慢得多。在许多情况下,使用定点技术可以在可接受的精度下提高性能。
答案 3 :(得分:1)
通常情况下,这样的微处理器既带有驱动程序包,也带有完整的BSP(板载支持包,由连接在一起的驱动程序和OS组成),两者都包含FP库例程。
编译器用等效的函数调用替换每个浮点运算。应该考虑这一点,特别是在迭代地调用此类操作时(在for
/ while
循环内),因为编译器无法应用循环展开优化。
不包括项目中所需库的结果将是链接错误。