GCC 关键字inline探究
生活随笔
收集整理的這篇文章主要介紹了
GCC 关键字inline探究
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、inline介紹
先看造型:
inline int test() { ? ? ...... ? ? return 0; }
int main() { ? ? test(); ? ? return 0; }
我們知道,如果test函數(shù)沒(méi)有inline關(guān)鍵字修飾的時(shí)候,程序執(zhí)行到調(diào)用test的時(shí)候,會(huì)從main函數(shù)跳到test函數(shù)執(zhí)行。為了從test函數(shù)返回到mian函數(shù)后,能從調(diào)用test函數(shù)的下一條指令執(zhí)行,在調(diào)用test函數(shù)前,我們必須對(duì)現(xiàn)場(chǎng)進(jìn)行保護(hù)(將一些寄存器的值壓棧)。
那如果加了inline關(guān)鍵字呢,那編譯系統(tǒng)就會(huì)將test函數(shù)當(dāng)做一個(gè)宏來(lái)處理,即直接在main函數(shù)中展開(kāi)。在這里需要注意的是,并不是所有函數(shù)加上inline關(guān)鍵字就一定會(huì)在main函數(shù)中展開(kāi),一般要求inline關(guān)鍵字盡可能的簡(jiǎn)單。
二、反匯編看效果
源碼:
#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
總結(jié)如下: 對(duì)于inine關(guān)鍵字,如果在編譯的時(shí)候不加優(yōu)化選項(xiàng)(-O 或 -O2)時(shí),編譯系統(tǒng)不會(huì)將其修飾的函數(shù)在mian函數(shù)中展開(kāi)。但是會(huì)把被inline修飾的函數(shù) 代碼按其在main函數(shù)中的調(diào)用順序放在main后面。 如果在編譯的時(shí)候加了優(yōu)化選項(xiàng),被inline修飾的函數(shù)大部分情況下會(huì)在main函數(shù)中展開(kāi)。
注意:inline是一個(gè)建議型關(guān)鍵字,具體有沒(méi)有被展開(kāi)反匯編一看便知。
原文地址: http://blog.chinaunix.net/uid-26833883-id-3351281.html
先看造型:
inline int test() { ? ? ...... ? ? return 0; }
int main() { ? ? test(); ? ? return 0; }
我們知道,如果test函數(shù)沒(méi)有inline關(guān)鍵字修飾的時(shí)候,程序執(zhí)行到調(diào)用test的時(shí)候,會(huì)從main函數(shù)跳到test函數(shù)執(zhí)行。為了從test函數(shù)返回到mian函數(shù)后,能從調(diào)用test函數(shù)的下一條指令執(zhí)行,在調(diào)用test函數(shù)前,我們必須對(duì)現(xiàn)場(chǎng)進(jìn)行保護(hù)(將一些寄存器的值壓棧)。
那如果加了inline關(guān)鍵字呢,那編譯系統(tǒng)就會(huì)將test函數(shù)當(dāng)做一個(gè)宏來(lái)處理,即直接在main函數(shù)中展開(kāi)。在這里需要注意的是,并不是所有函數(shù)加上inline關(guān)鍵字就一定會(huì)在main函數(shù)中展開(kāi),一般要求inline關(guān)鍵字盡可能的簡(jiǎn)單。
二、反匯編看效果
源碼:
#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
總結(jié)如下: 對(duì)于inine關(guān)鍵字,如果在編譯的時(shí)候不加優(yōu)化選項(xiàng)(-O 或 -O2)時(shí),編譯系統(tǒng)不會(huì)將其修飾的函數(shù)在mian函數(shù)中展開(kāi)。但是會(huì)把被inline修飾的函數(shù) 代碼按其在main函數(shù)中的調(diào)用順序放在main后面。 如果在編譯的時(shí)候加了優(yōu)化選項(xiàng),被inline修飾的函數(shù)大部分情況下會(huì)在main函數(shù)中展開(kāi)。
注意:inline是一個(gè)建議型關(guān)鍵字,具體有沒(méi)有被展開(kāi)反匯編一看便知。
原文地址: http://blog.chinaunix.net/uid-26833883-id-3351281.html
總結(jié)
以上是生活随笔為你收集整理的GCC 关键字inline探究的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux 标准IO缓冲机制探究
- 下一篇: Linux 内核自解压流程分析