在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

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

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

            作者: 時(shí)間:2016-12-01 來(lái)源:網(wǎng)絡(luò) 收藏
            我的測(cè)試環(huán)境:Fedora14
            Gcc版本:gcc-4.5.1
            內(nèi)核版本:2.6.38.1
            C語(yǔ)言是一個(gè)強(qiáng)大的語(yǔ)言,特別是對(duì)于嵌入式開發(fā)過(guò)程中有時(shí)需要反匯編分析代碼中存在的問題,函數(shù)是C語(yǔ)言中的難點(diǎn),關(guān)于函數(shù)的調(diào)用也是很多人不能理解的,很多知道的也是一知半解。對(duì)C語(yǔ)言的調(diào)用有了一個(gè)比較清晰的認(rèn)識(shí)就能夠更清晰的分析代碼中存在的問題。我也是看了很多的資料,然后自己寫了一一段小代碼作為分析的測(cè)試代碼。首先記住在X86體系里很多的寄存器都有特殊的用途,其中ESP表示當(dāng)前函數(shù)堆棧的棧頂指針,而EBP則表示當(dāng)前函數(shù)堆棧的基地址。EBP是?;返闹羔槪肋h(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語(yǔ)言的入口都是從main函數(shù)開始的,但是從反匯編代碼中可以發(fā)現(xiàn)并不是只有自己設(shè)計(jì)的代碼,還存在很多關(guān)于初始化等操作。這主要是因?yàn)镃語(yǔ)言的運(yùn)行需要一些基本的環(huán)境和C-RunTime的一些基本函數(shù)。因此main 函數(shù)只是我們C語(yǔ)言的入口,但并不是一個(gè)程序的開始。因此main函數(shù)也需要堆棧的控制,也需要壓棧出棧等操作。
            需要注意的是:
            上一頁(yè) 1 2 3 下一頁(yè)

            評(píng)論


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

            關(guān)閉