教你用Windows API 寫一個Thread類(不使用static哦)——(2)

來源:互聯網
上載者:User

    這一文章中我們主要分析VS平台對於函數調用的編譯處理,首先我們看一個簡單的例子,代碼如下:

        void Hello(){        }        int main(){             Hello();        }

    然後在VS Command Prompt下面用cl -FA main.cpp 編譯一下,你會得到一個彙編的檔案main.asm,其內容如下:

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01  TITLE E:\bossjue\main.cpp .686P .XMM include listing.inc .model flatINCLUDELIB LIBCMTINCLUDELIB OLDNAMESPUBLIC ?Hello@@YAXXZ     ; Hello; Function compile flags: /Odtp_TEXT SEGMENT?Hello@@YAXXZ PROC     ; Hello; File e:\bossjue\main.cpp; Line 1 push ebp mov ebp, esp; Line 2 pop ebp ret 0?Hello@@YAXXZ ENDP     ; Hello_TEXT ENDSPUBLIC _main; Function compile flags: /Odtp_TEXT SEGMENT_main PROC; Line 4 push ebp mov ebp, esp; Line 5 call ?Hello@@YAXXZ    ; Hello; Line 6 xor eax, eaxpop ebp ret 0_main ENDP_TEXT ENDSEND

    別怕,有我給你們解釋這些代碼,這些代碼可以說其實都不用看,只需要看有標記;Line 1、;Line 2……這些行就行了,首先在Lin 4,這是main函數的開始,裡面首先儲存了棧幀,然後Lin 5那裡跳到Hello函數裡面去執行Hello裡面的代碼。也就是說,如果我們寫以下的代碼也應該是對的。

void Hello(){}int main(){    __asm{        call Hello    }}


 

    可以編譯,看到程式正常運行,說明我們的call調用是成功的,在此說明了一點,函數調用最後關鍵的一步是call調用。

上面只是簡單的一個Hello函數,下面我們用難一點的去測試,我們寫如下代碼:

int Hello(){    return 100;}int main(){    Hello();}


 

    這個代碼和上面代碼的區別在於這個函數Hello 有傳回值,同樣地用cl -FA main.cpp編譯得到main.asm,開啟main.asm看到其內容如下:

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 TITLE E:\bossjue\main.cpp .686P .XMM include listing.inc .model flatINCLUDELIB LIBCMTINCLUDELIB OLDNAMESPUBLIC ?Hello@@YAHXZ     ; Hello; Function compile flags: /Odtp_TEXT SEGMENT?Hello@@YAHXZ PROC     ; Hello; File e:\bossjue\main.cpp; Line 1 push ebp mov ebp, esp; Line 2 mov eax, 100    ; 00000064H; Line 3 pop ebp ret 0?Hello@@YAHXZ ENDP     ; Hello_TEXT ENDSPUBLIC _main; Function compile flags: /Odtp_TEXT SEGMENT_main PROC; Line 5 push ebp mov ebp, esp; Line 6 call ?Hello@@YAHXZ    ; Hello; Line 7 xor eax, eax pop ebp ret 0_main ENDP_TEXT ENDSEND

    在Line2裡面可以看到有一句mov eax, 100,聯想到Hello裡面返回100,可以猜測VS裡面是用eax傳遞傳回值的,其實確實是這樣的,可以用下面的代碼測試:

#include <iostream>using namespace std;int Hello(){    __asm{        mov eax, 100   }}int main(){    cout<<Hello()<<endl;}

    可以看到輸出100,說明我了們的結果是對的,函數的傳回值是存放在eax進而的。

下面我們再給Hello傳遞參數試試,來進一步說明參數傳遞的原理代碼如下

void Hello(int iVA, int iVB){}int main(){    Hello(3, 5);}


 

    同樣的得到彙編的代碼如下:

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01  TITLE E:\bossjue\main.cpp .686P .XMM include listing.inc .model flatINCLUDELIB LIBCMTINCLUDELIB OLDNAMESPUBLIC ?Hello@@YAXHH@Z     ; Hello; Function compile flags: /Odtp_TEXT SEGMENT_iVA$ = 8      ; size = 4_iVB$ = 12      ; size = 4?Hello@@YAXHH@Z PROC     ; Hello; File e:\bossjue\main.cpp; Line 1 push ebp mov ebp, esp; Line 3 pop ebp ret 0?Hello@@YAXHH@Z ENDP     ; Hello_TEXT ENDSPUBLIC _main; Function compile flags: /Odtp_TEXT SEGMENT_main PROC; Line 5 push ebp mov ebp, esp; Line 6 push 5 push 3 call ?Hello@@YAXHH@Z    ; Hello add esp, 8; Line 7 xor eax, eax pop ebp ret 0_main ENDP_TEXT ENDSEND

    可以看到,其實不過是把參數用push傳遞進了stack裡面,然後就是一個call而已,當然是主調函數清除stack(一句add esp而已)

為了測試,我們寫下如下的代碼

#include <stdio.h>int main(){    char *lpstrFormat = "%s %d";    char *lpStr   = "Hello, this year is: ";    __asm{        push 2012        push lpStr        push lpstrFormat        call printf        add esp, 12   }}

    然後在命令列裡面運行得到了你想要的結果,呵呵。
當然,參數怎麼傳遞的和誰清除stack這個由調用方式決定的,調用方式一般有三種__stdcall, __cdecl, __fastcall,讀都可以在網上baidu一下,或者過幾天我自己寫文章說明。

    到此,一般函數調用的過程已經完全說完了,如果想知道class的成員函數的調用過程,我在下一文章中說明。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.