新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > C語言函數(shù)調(diào)用分析

        C語言函數(shù)調(diào)用分析

        作者: 時(shí)間:2016-12-01 來源:網(wǎng)絡(luò) 收藏
        我的測(cè)試環(huán)境:Fedora14
        Gcc版本:gcc-4.5.1
        內(nèi)核版本:2.6.38.1
        C語言是一個(gè)強(qiáng)大的語言,特別是對(duì)于嵌入式開發(fā)過程中有時(shí)需要反匯編分析代碼中存在的問題,函數(shù)是C語言中的難點(diǎn),關(guān)于函數(shù)的調(diào)用也是很多人不能理解的,很多知道的也是一知半解。對(duì)C語言的調(diào)用有了一個(gè)比較清晰的認(rèn)識(shí)就能夠更清晰的分析代碼中存在的問題。我也是看了很多的資料,然后自己寫了一一段小代碼作為分析的測(cè)試代碼。首先記住在X86體系里很多的寄存器都有特殊的用途,其中ESP表示當(dāng)前函數(shù)堆棧的棧頂指針,而EBP則表示當(dāng)前函數(shù)堆棧的基地址。EBP是棧基址的指針,永遠(yuǎn)指向棧底(高地址),ESP是棧指針,永遠(yuǎn)指向棧頂(低地址)。
        我的代碼如下:
        1. #include

        2. intpluss_a_and_b(inta,intb)
        3. {
        4. intc=-2;
        5. return(a+b-c);
        6. }
        7. intcall_plus(int*a,int*b)
        8. {
        9. intc=*a;
        10. intd=*b;

        11. *a=d;
        12. *b=c;
        13. return pluss_a_and_b(c,d);
        14. }
        15. intmain()
        16. {
        17. intc=10;
        18. intd=20;
        19. intg=call_plus(&c,&d);
        20. return 0;
        21. }
        對(duì)上面的代碼進(jìn)行編譯和反匯編:
        [gong@Gong-Computer deeplearn]$ gcc -g testcall.c -o testcall
        [gong@Gong-Computer deeplearn]$ objdump -S -d testcall > testcall_s
        然后對(duì)反匯編的代碼進(jìn)行分析:
        1. ...
        2. 8048393: c3 ret
        3. 08048394 :
        4. #include
        5. int pluss_a_and_b(int a,int b)
        6. {
        7. 8048394: 55 push %ebp
        8. 8048395: 89 e5 mov %esp,%ebp
        9. 8048397: 83 ec 10 sub $0x10,%esp
        10. int c = -2;
        11. 804839a: c7 45 fc fe ff ff ff movl $0xfffffffe,-0x4(%ebp)
        12. return (a + b - c);
        13. 80483a1: 8b 45 0c mov 0xc(%ebp),%eax
        14. 80483a4: 8b 55 08 mov 0x8(%ebp),%edx
        15. 80483a7: 8d 04 02 lea (%edx,%eax,1),%eax
        16. 80483aa: 2b 45 fc sub -0x4(%ebp),%eax
        17. }
        18. 80483ad: c9 leave
        19. 80483ae: c3 ret
        20. 080483af :
        21. intcall_plus(int *a,int *b)
        22. {
        23. 80483af: 55 push %ebp
        24. 80483b0: 89 e5 mov %esp,%ebp
        25. 80483b2: 83 ec 18 sub $0x18,%esp
        26. int c = *a;
        27. 80483b5: 8b 45 08 mov 0x8(%ebp),%eax
        28. 80483b8: 8b 00 mov (%eax),%eax
        29. 80483ba: 89 45 fc mov %eax,-0x4(%ebp)
        30. int d = *b;
        31. 80483bd: 8b 45 0c mov 0xc(%ebp),%eax
        32. 80483c0: 8b 00 mov (%eax),%eax
        33. 80483c2: 89 45 f8 mov %eax,-0x8(%ebp)
        34. *a = d;
        35. 80483c5: 8b 45 08 mov 0x8(%ebp),%eax
        36. 80483c8: 8b 55 f8 mov -0x8(%ebp),%edx
        37. 80483cb: 89 10 mov %edx,(%eax)
        38. *b = c;
        39. 80483cd: 8b 45 0c mov 0xc(%ebp),%eax
        40. 80483d0: 8b 55 fc mov -0x4(%ebp),%edx
        41. 80483d3: 89 10 mov %edx,(%eax)
        42. return pluss_a_and_b(c,d);
        43. 80483d5: 8b 45 f8 mov -0x8(%ebp),%eax
        44. 80483d8: 89 44 24 04 mov %eax,0x4(%esp)
        45. 80483dc: 8b 45 fc mov -0x4(%ebp),%eax
        46. 80483df: 89 04 24 mov %eax,(%esp)
        47. 80483e2: e8 ad ff ff ff call 8048394
        48. }
        49. 80483e7: c9 leave
        50. 80483e8: c3 ret
        51. 080483e9
          :
        52. int main()
        53. {
        54. 80483e9: 55 push %ebp
        55. 80483ea: 89 e5 mov %esp,%ebp
        56. 80483ec: 83 ec 18 sub $0x18,%esp
        57. int c = 10;
        58. 80483ef: c7 45 f8 0a 00 00 00 movl $0xa,-0x8(%ebp)
        59. int d = 20;
        60. 80483f6: c7 45 f4 14 00 00 00 movl $0x14,-0xc(%ebp)
        61. int g =call_plus(&c,&d);
        62. 80483fd: 8d 45 f4 lea -0xc(%ebp),%eax
        63. 8048400: 89 44 24 04 mov %eax,0x4(%esp)
        64. 8048404: 8d 45 f8 lea -0x8(%ebp),%eax
        65. 8048407: 89 04 24 mov %eax,(%esp)
        66. 804840a: e8 a0 ff ff ff call 80483af
        67. 804840f: 89 45 fc mov %eax,-0x4(%ebp)
        68. return 0;
        69. 8048412: b8 00 00 00 00 mov $0x0,%eax
        70. }
        71. 8048417: c9 leave
        72. 8048418: c3 ret
        73. 8048419: 90 nop
        74. 804841a: 90nop
        75. ...
        首先,C語言的入口都是從main函數(shù)開始的,但是從反匯編代碼中可以發(fā)現(xiàn)并不是只有自己設(shè)計(jì)的代碼,還存在很多關(guān)于初始化等操作。這主要是因?yàn)镃語言的運(yùn)行需要一些基本的環(huán)境和C-RunTime的一些基本函數(shù)。因此main 函數(shù)只是我們C語言的入口,但并不是一個(gè)程序的開始。因此main函數(shù)也需要堆棧的控制,也需要壓棧出棧等操作。
        需要注意的是:
        上一頁 1 2 3 下一頁

        關(guān)鍵詞: C語言函數(shù)調(diào)

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 小金县| 名山县| 昭苏县| 昂仁县| 容城县| 白山市| 云和县| 涿鹿县| 平罗县| 新郑市| 太仓市| 离岛区| 永善县| 南京市| 酉阳| 亚东县| 景德镇市| 黔南| 调兵山市| 雷山县| 龙井市| 成安县| 黑龙江省| 临高县| 晋宁县| 肥乡县| 古交市| 丰城市| 宝丰县| 丹凤县| 靖远县| 肥乡县| 武川县| 乌拉特后旗| 江津市| 东海县| 通州区| 简阳市| 洪泽县| 云阳县| 大洼县|