高效的C编程之: 函数调用(补充)

来源:本站
导读:目前正在解读《高效的C编程之: 函数调用(补充)》的相关信息,《高效的C编程之: 函数调用(补充)》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《高效的C编程之: 函数调用(补充)》的详细说明。
简介:函数设计的基本原则是使其函数体尽量的小。这样编译器可以对函数做更多的优化。(EEFOCUS)

14.9.6内嵌函数

ARM编译器支持函数内嵌功能。使用关键字“_inline”声明函数,可以使函数内嵌。下面的例子显示了如何使用函数内嵌功能。

程序源文件如下。

__inlineintsquare(intx)

{

returnx*x;

}

#include<math.h>

doublelength(intx,inty)

{

returnsqrt(square(x)+square(y));

}

编译结果如下所示。

length

STMDBsp!,{lr}

MULa3,a1,a1

MLAa1,a2,a2,a3

BL_dflt

LDMIAsp!,{lr}

Bsqrt

使用函数内嵌有以下好处:

·减少了函数调用开销(如寄存器的压栈保护);

·减少了参数传递开销;

·进一步提高了编译器对代码优化的可能性(如编译器可将ADD和MUL指令合并为一条MLA指令)。

但使用函数内嵌将增加代码尺寸。也正是处于这种原因,armcc和tcc都没有提供函数自动内嵌的编译选项。

一般来说,只有对性能影响较大的重要函数才使用关键字_inline进行内嵌。

14.9.7函数定义

使用函数时要先定义后调用是ARM编程的基本规则之一。在函数调用之前定义函数,编译器可以检查被调用函数的寄存器使用情况,从而对其进行进一步的优化。

首先来看下面的例子。

intsquare(intx);

intsumsquares1(intx,inty)

{

returnsquare(x)+square(y);

}

/*square函数可以在本文件中定义,也可以在其他源文件中定义*/

intsquare(intx)

{

returnx*x;

}

intsumsquares2(intx,inty)

{

returnsquare(x)+square(y);

}

编译的结果如下所示。

sumsquares1

STMDBsp!,{v1,v2,lr}

MOVv1,a2

BLsquare

MOVv2,a1

MOVa1,v1

BLsquare

ADDa1,v2,a1

LDMIAsp!,{v1,v2,pc}

square

MOVa2,a1

MULa1,a2,a2

MOVpc,lr

sumsquares2

STMDBsp!,{lr}

MOVa3,a2

BLsquare

MOVa4,a1

MOVa1,a3

BLsquare

ADDa1,a4,a1

LDMIAsp!,{pc}

从编译的结果可以看出,将square函数定义放在sumsquares函数前,编译器可以判断寄存器a3和a4并未使用,所有在调用函数入口处并未将其压栈。这样,减少了内存访问,提高了代码执行效率。

提醒:《高效的C编程之: 函数调用(补充)》最后刷新时间 2024-03-14 01:07:24,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《高效的C编程之: 函数调用(补充)》该内容的真实性请自行鉴别。