一、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 movip, sp
    83d8:e92dd800 push{fp, ip, lr, pc}
    83dc:e24cb004 subfp, ip, #4; 0x4
    83e0:eb000005 bl83fc
    83e4:eb000012 bl8434
    83e8:e3a03000 movr3, #0; 0x0
    83ec:e1a00003 movr0, r3
    83f0:e24bd00c subsp, fp, #12; 0xc
    83f4:e89d6800 ldmsp, {fp, sp, lr}
    83f8:e12fff1e bxlr

000083fc :
    83fc:e1a0c00d movip, sp
    8400:e92dd800 push{fp, ip, lr, pc}
    8404:e24cb004 subfp, ip, #4; 0x4
    8408:e24dd008 subsp, sp, #8; 0x8
    840c:e3a03001 movr3, #1; 0x1
    8410:e50b3010 strr3, [fp, #-16]
    8414:e59f0014 ldrr0, [pc, #20]; 8430
    8418:ebffffb9 bl8304
    841c:e51b3010 ldrr3, [fp, #-16]
    8420:e1a00003 movr0, r3
    8424:e24bd00c subsp, fp, #12; 0xc
    8428:e89d6800 ldmsp, {fp, sp, lr}
    842c:e12fff1e bxlr
    8430:00008504 .word0x00008504

00008434 :
    8434:e1a0c00d movip, sp
    8438:e92dd800 push{fp, ip, lr, pc}
    843c:e24cb004 subfp, ip, #4; 0x4
    8440:e24dd008 subsp, sp, #8; 0x8
    8444:e3a03002 movr3, #2; 0x2
    8448:e50b3010 strr3, [fp, #-16]
    844c:e59f0014 ldrr0, [pc, #20]; 8468
    8450:ebffffab bl8304
    8454:e51b3010 ldrr3, [fp, #-16]
    8458:e1a00003 movr0, r3
    845c:e24bd00c subsp, fp, #12; 0xc
    8460:e89d6800 ldmsp, {fp, sp, lr}
    8464:e12fff1e bxlr
    8468:00008514 .word0x00008514

第二次编译

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 subsp, sp, #4; 0x4
    83dc:e59f0018 ldrr0, [pc, #24]; 83fc
    83e0:ebffffc7 bl8304
    83e4:e59f0014 ldrr0, [pc, #20]; 8400
    83e8:ebffffc5 bl8304
    83ec:e3a00000 movr0, #0; 0x0
    83f0:e28dd004 addsp, sp, #4; 0x4
    83f4:e49de004 pop{lr}; (ldr lr, [sp], #4)
    83f8:e12fff1e bxlr
    83fc:0000849c .word0x0000849c
    8400:000084ac .word0x000084ac

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

注意:inline是一个建议型关键字,具体有没有被展开反汇编一看便知。
12-28 07:05