Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104433
  • 博文数量: 33
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 45
  • 用 户 组: 普通用户
  • 注册时间: 2016-11-04 11:29
个人简介

所学,所得,所知

文章分类

全部博文(33)

文章存档

2017年(28)

2016年(5)

我的朋友

分类: C/C++

2017-02-07 17:03:46

原文地址:GCC 关键字inline探究 作者:草根老师

一、inline介绍

先看造型:

inline int test()
{
    ......
    return 0;
}

int main()
{
    test();
    return 0;
}

我们知道,如果test函数没有inline关键字修饰的时候,程序执行到调用test的时候,会从main函数跳到test函数执行。为了从test函数返回到mian函数后,能从调用test函数的下一条指令执行,在调用test函数前,我们必须对现场进行保护(将一些寄存器的值压栈)。

那如果加了inline关键字呢,那编译系统就会将test函数当做一个宏来处理,即直接在main函数中展开。在这里需要注意的是,并不是所有函数加上inline关键字就一定会在main函数中展开,一般要求inline关键字尽可能的简单。

二、反汇编看效果

源码:

#include

static inline int test1()
{
int a = 1;

printf("Hello test1.\n");

return a;
}

static inline int test2()
{
int b = 2;

printf("Hello test2.\n");

return b;
}

int main()
{
test1();
test2();

return 0;
}

第一次编译:
arm-none-linux-gnueabi-gcc inline.c -o inline

反汇编如下:
arm-none-linux-gnueabi-objdump -d inline > log

查看log文件
cat log:

部分汇编代码
000083d4
:
    83d4: e1a0c00d  mov ip, sp
    83d8: e92dd800  push {fp, ip, lr, pc}
    83dc: e24cb004  sub fp, ip, #4 ; 0x4
    83e0: eb000005  bl 83fc
    83e4: eb000012  bl 8434
    83e8: e3a03000  mov r3, #0 ; 0x0
    83ec: e1a00003  mov r0, r3
    83f0: e24bd00c  sub sp, fp, #12 ; 0xc
    83f4: e89d6800  ldm sp, {fp, sp, lr}
    83f8: e12fff1e  bx lr

000083fc :
    83fc: e1a0c00d  mov ip, sp
    8400: e92dd800  push {fp, ip, lr, pc}
    8404: e24cb004  sub fp, ip, #4 ; 0x4
    8408: e24dd008  sub sp, sp, #8 ; 0x8
    840c: e3a03001  mov r3, #1 ; 0x1
    8410: e50b3010  str r3, [fp, #-16]
    8414: e59f0014  ldr r0, [pc, #20] ; 8430
    8418: ebffffb9  bl 8304 <_init+0x50>
    841c: e51b3010  ldr r3, [fp, #-16]
    8420: e1a00003  mov r0, r3
    8424: e24bd00c  sub sp, fp, #12 ; 0xc
    8428: e89d6800  ldm sp, {fp, sp, lr}
    842c: e12fff1e  bx lr
    8430: 00008504  .word 0x00008504

00008434 :
    8434: e1a0c00d  mov ip, sp
    8438: e92dd800  push {fp, ip, lr, pc}
    843c: e24cb004  sub fp, ip, #4 ; 0x4
    8440: e24dd008  sub sp, sp, #8 ; 0x8
    8444: e3a03002  mov r3, #2 ; 0x2
    8448: e50b3010  str r3, [fp, #-16]
    844c: e59f0014  ldr r0, [pc, #20] ; 8468
    8450: ebffffab  bl 8304 <_init+0x50>
    8454: e51b3010  ldr r3, [fp, #-16]
    8458: e1a00003  mov r0, r3
    845c: e24bd00c  sub sp, fp, #12 ; 0xc
    8460: e89d6800  ldm sp, {fp, sp, lr}
    8464: e12fff1e  bx lr
    8468: 00008514  .word 0x00008514

第二次编译

arm-none-linux-gnueabi-gcc -O  inline.c -o inline

反汇编如下:
arm-none-linux-gnueabi-objdump -d inline > log

查看log文件
cat log:

000083d4
:
    83d4: e52de004  push {lr} ; (str lr, [sp, #-4]!)
    83d8: e24dd004  sub sp, sp, #4 ; 0x4
    83dc: e59f0018  ldr r0, [pc, #24] ; 83fc
    83e0: ebffffc7  bl 8304 <_init+0x50>
    83e4: e59f0014  ldr r0, [pc, #20] ; 8400
    83e8: ebffffc5  bl 8304 <_init+0x50>
    83ec: e3a00000  mov r0, #0 ; 0x0
    83f0: e28dd004  add sp, sp, #4 ; 0x4
    83f4: e49de004  pop {lr} ; (ldr lr, [sp], #4)
    83f8: e12fff1e  bx lr
    83fc: 0000849c  .word 0x0000849c
    8400: 000084ac  .word 0x000084ac

总结如下:
对于inine关键字,如果在编译的时候不加优化选项(-O 或 -O2)时,编译系统不会将其修饰的函数在mian函数中展开。但是会把被inline修饰的函数 代码按其在main函数中的调用顺序放在main后面。
如果在编译的时候加了优化选项,被inline修饰的函数大部分情况下会在main函数中展开。

注意:inline是一个建议型关键字,具体有没有被展开反汇编一看便知。
阅读(1620) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~