新聞中心

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

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

        作者: 時(shí)間:2016-12-01 來源:網(wǎng)絡(luò) 收藏
        代碼:
        1. #include

        2. typedef struct{
        3. doubled;
        4. float f;
        5. inti;
        6. char c;
        7. }return_value;

        8. return_value my_test_pass(return_value pass)
        9. {
        10. return_value rv;
        11. rv.d=pass.d;
        12. rv.f=pass.f;
        13. rv.i=pass.i;
        14. rv.c=pass.c;

        15. return rv;
        16. }
        17. return_value my_test_of_return()
        18. {
        19. return_value rv;

        20. rv.d=12.56;
        21. rv.f=3.1;
        22. rv.i=10;
        23. rv.c=a;

        24. return rv;
        25. }

        26. intmain()
        27. {
        28. return_value local=my_test_of_return();
        29. return_value local1=my_test_pass(local);

        30. return 0;
        31. }
        編譯和反匯編過程:
        [gong@Gong-Computer deeplearn]$ gcc -g structpass.c -o structpass
        [gong@Gong-Computer deeplearn]$ objdump -S -d structpass > structpass_s
        1. ...
        2. int main()
        3. {
        4. 804841d: 8d 4c 24 04 lea 0x4(%esp),%ecx
        5. 8048421: 83 e4 f8 and $0xfffffff8,%esp
        6. 8048424: ff 71 fc pushl -0x4(%ecx)
        7. 8048427: 55 push %ebp
        8. 8048428: 89 e5 mov %esp,%ebp
        9. 804842a: 51 push %ecx
        10. 804842b: 83 ec 4c sub $0x4c,%esp
        11. return_value local = my_test_of_return();
        12. 804842e: 8d 45 e0 lea -0x20(%ebp),%eax
        13. 8048431: 89 04 24 mov %eax,(%esp)
        14. 8048434: e8 9e ff ff ff call 80483d7
        15. 8048439: 83 ec 04 sub $0x4,%esp
        16. return_value local1 = my_test_pass(local);
        17. 804843c: 8d 45 c8 lea -0x38(%ebp),%eax
        18. 804843f: 8b 55 e0 mov -0x20(%ebp),%edx
        19. 8048442: 89 54 24 04 mov %edx,0x4(%esp)
        20. 8048446: 8b 55 e4 mov -0x1c(%ebp),%edx
        21. 8048449: 89 54 24 08 mov %edx,0x8(%esp)
        22. 804844d: 8b 55 e8 mov -0x18(%ebp),%edx
        23. 8048450: 89 54 24 0c mov %edx,0xc(%esp)
        24. 8048454: 8b 55 ec mov -0x14(%ebp),%edx
        25. 8048457: 89 54 24 10 mov %edx,0x10(%esp)
        26. 804845b: 8b 55 f0 mov -0x10(%ebp),%edx
        27. 804845e: 89 54 24 14 mov %edx,0x14(%esp)
        28. 8048462: 89 04 24 mov %eax,(%esp)
        29. 8048465: e8 2a ff ff ffcall8048394
        30. 804846a: 83 ec 04 sub $0x4,%esp
        31. return 0;
        32. 804846d: b8 00 00 00 00 mov $0x0,%eax
        33. }
        ...
        由上面的反匯編代碼可以知道結(jié)構(gòu)體的傳遞參數(shù)是依據(jù)堆棧實(shí)現(xiàn)的。這也說明了多參數(shù)的傳遞過程并不是按著固定的模式實(shí)現(xiàn)的,這也是我們需要注意的問題。參數(shù)的傳遞需要根據(jù)實(shí)際情況分析。
        總結(jié):
        函數(shù)的調(diào)用是有一定的方式的,各個(gè)函數(shù)都有一定的堆棧空間,而且每一個(gè)堆棧空間的分布情況也是類似的,但是大小要根據(jù)實(shí)際的情況分析。一般一個(gè)函數(shù)的堆棧空間中包含下面幾個(gè)部分:1、棧幀(用來表示該堆棧空間的棧底,也就是指開始的地址EBP),局部變量的空間,下一個(gè)被調(diào)用函數(shù)的參數(shù)傳遞,最后是返回地址(實(shí)質(zhì)上也是一個(gè)EBP)。就是依據(jù)EBP和相對位置就能知道每一個(gè)函數(shù)的基本分布,而ESP就能知道堆棧空間的大小。
        被調(diào)用參數(shù)的獲取主要是依據(jù)EBP指針的相對位置獲得,因?yàn)楸徽{(diào)用函數(shù)的堆棧空間上一個(gè)堆棧空間就是調(diào)用函數(shù)的堆棧空間。根據(jù)函數(shù)的棧幀指針(EBP)和相對位置(-4,-8等)找到對應(yīng)的參數(shù),但是相對位置也是不固定的,這需要考慮結(jié)構(gòu)體的對齊等方式,具體的要在實(shí)際中計(jì)算。
        返回值一般都是采用EAX返回的,但是對于結(jié)構(gòu)體等則是采用堆棧的方式一個(gè)元算一個(gè)元素的返回的,但是還是運(yùn)用了EAX的特性。
        函數(shù)調(diào)用的分布打開如下:

        從上面的分析我們可以發(fā)現(xiàn)匯編代碼是非常有用的,建議多參看匯編代碼分析具體的問題。
        上一頁 1 2 3 下一頁

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

        評論


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

        關(guān)閉
        主站蜘蛛池模板: 江都市| 岳西县| 新乡县| 思茅市| 稻城县| 苗栗县| 禄劝| 保亭| 常熟市| 永修县| 万全县| 浦东新区| 嵊州市| 鄂尔多斯市| 屏南县| 长治县| 青铜峡市| 聂荣县| 山东省| 庄河市| 当雄县| 颍上县| 石渠县| 兰西县| 花莲县| 奉化市| 旬阳县| 陈巴尔虎旗| 新晃| 赞皇县| 新郑市| 陆良县| 吉林省| 淳安县| 建始县| 扎囊县| 牟定县| 陆良县| 湖北省| 宁南县| 南安市|