一、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 <stdio.h>
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 <main>:
83d4:
e1a0c00d
mov ip, sp
83d8:
e92dd800
push {fp, ip, lr, pc}
83dc:
e24cb004
sub fp, ip, #4
; 0x4
83e0:
eb000005
bl 83fc <test1>
83e4:
eb000012
bl 8434 <test2>
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 <test1>:
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 <test1+0x34>
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 <test2>:
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 <test2+0x34>
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 <main>:
83d4:
e52de004
push {lr}
; (str lr, [sp, #-4]!)
83d8:
e24dd004
sub sp, sp, #4
; 0x4
83dc:
e59f0018
ldr r0, [pc, #24]
; 83fc <main+0x28>
83e0:
ebffffc7
bl 8304 <_init+0x50>
83e4:
e59f0014
ldr r0, [pc, #20]
; 8400 <main+0x2c>
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是一个建议型关键字,具体有没有被展开反汇编一看便知。
原文地址: http://blog.chinaunix.net/uid-26833883-id-3351281.html
原文地址: http://blog.chinaunix.net/uid-26833883-id-3351281.html