亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go語言調用約定多返回值實現原理是什么

發布時間:2022-05-24 17:23:53 來源:億速云 閱讀:267 作者:iii 欄目:開發技術

這篇文章主要介紹了go語言調用約定多返回值實現原理是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇go語言調用約定多返回值實現原理是什么文章都會有所收獲,下面我們一起來看看吧。

    go簡單代碼反匯編

    用簡單的代碼用以分析go的調用約定及多返回值的返回方式。

    package main
    
    func vals(c, d int) (a int, b int) {
    	e := 1
    	f := 2
    	a = c + d + e + f
    	b = d * 2
    	return
    }
    
    func testMutil() {
    	i, j := vals(1, 2)
    	i = i + 1
    	j = j + 1
    }
    
    func main() {
    	testMutil()
    }

    編譯go build -gcflags "-N -l" test.go并通過反編譯軟件獲得部分匯編:

    main_vals:
        sub     rsp, 18h
        mov     [rsp+18h+var_8], rbp
        lea     rbp, [rsp+18h+var_8]
        mov     [rsp+18h+arg_10], 0
        mov     [rsp+18h+arg_18], 0
        mov     [rsp+18h+var_10], 1
        mov     [rsp+18h+var_18], 2
        mov     rax, [rsp+18h+arg_0]
        add     rax, [rsp+18h+arg_8]
        add     rax, [rsp+18h+var_10]
        add     rax, 2
        mov     [rsp+18h+arg_10], rax
        mov     rax, [rsp+18h+arg_8]
        shl     rax, 1
        mov     [rsp+18h+arg_18], rax
        mov     rbp, [rsp+18h+var_8]
        add     rsp, 18h
        retn
    main_vals endp
    
    main_testMutil:
        mov     rcx, gs:28h
        mov     rcx, [rcx+0]
        cmp     rsp, [rcx+10h]
        jbe     short morestack_noctxt
        sub     rsp, 48h
        mov     [rsp+48h+var_8], rbp
        lea     rbp, [rsp+48h+var_8]
        mov     [rsp+48h+var_48], 1
        mov     [rsp+48h+var_40], 2
        call    main_vals
        mov     rax, [rsp+48h+var_38]
        mov     [rsp+48h+var_10], rax
        mov     rax, [rsp+48h+var_30]
        mov     [rsp+48h+var_18], rax
        mov     rax, [rsp+48h+var_10]
        mov     [rsp+48h+var_20], rax
        mov     rax, [rsp+48h+var_18]
        mov     [rsp+48h+var_28], rax
        mov     rax, [rsp+48h+var_20]
        inc     rax
        mov     [rsp+48h+var_20], rax
        mov     rax, [rsp+48h+var_28]
        inc     rax
        mov     [rsp+48h+var_28], rax
        mov     rbp, [rsp+48h+var_8]
        add     rsp, 48h
        retn
    morestack_noctxt:
        call    runtime_morestack_noctxt
    main_testMutil endp

    go語言調用約定分析

    1.C/C++調用約定類別

    __stdcall調用約定:函數的參數自右向左通過棧傳遞,被調用的函數在返回前清理傳送參數的內存棧。

    _cdecl是C和C++程序的缺省調用方式。每一個調用它的函數都包含清空堆棧的代碼,所以產生的可執行文件大小會比調用_stdcall函數的大。函數采用從右到左的壓棧方式。注意:對于可變參數的成員函數,始終使用__cdecl的轉換方式。

    __fastcall調用約定:它是通過寄存器來傳送參數的(實際上,它用ECX和EDX傳送前兩個雙字(DWORD)或更小的參數,剩下的參數仍舊自右向左壓棧傳送,被調用的函數在返回前清理傳送參數的內存棧)。

    thiscall僅僅應用于”C++”成員函數。this指針存放于CX寄存器,參數從右到左壓。thiscall不是關鍵詞,因此不能被程序員指定。

    naked call采用1-4的調用約定時,如果必要的話,進入函數時編譯器會產生代碼來保存ESI,EDI,EBX,EBP寄存器,退出函數時則產生代碼恢復這些寄存器的內容。naked call不產生這樣的代碼。naked call不是類型修飾符,故必須和_declspec共同使用。

    2.go語言調用約定

    sub     rsp, 18h
    mov     [rsp+18h+var_8], rbp
    ...
    mov     rbp, [rsp+18h+var_8]
    add     rsp, 18h

    這段代碼分別對應棧幀的構造與銷毀。
    根據反匯編并且調試,可以發現go語言參數是自右向左通過棧傳遞,被調用的函數在返回前清理傳送參數的內存棧。所以GO語言符合__stdcall調用約定。

    go語言如何實現多返回值的

    go語言可以返回多個返回值, 但同為編譯型語言的C、C++卻不支持。

    1.C/C++返回值返回方式。

    C/C++是通過eax/rax(32/64bit)寄存器返回的返回值。

    2.go語言多返回值返回方式

    可以看到vals函數的匯編,通過調試,可知arg_10與arg_18就是返回值a和b, arg_0與arg_8分別是參數c和d。其中

    mov     [rsp+18h+arg_10], rax
    ...
    mov     [rsp+18h+arg_18], rax

    分別將參數值返回到參數上。之后在main_testMutil中將參數返回值拷貝到對應局部變量中

    mov     rax, [rsp+48h+var_38]
    mov     [rsp+48h+var_10], rax
    mov     rax, [rsp+48h+var_30]
    mov     [rsp+48h+var_18], rax

    這就是go語言多返回值的實現方法了。

    關于“go語言調用約定多返回值實現原理是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“go語言調用約定多返回值實現原理是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    中山市| 甘泉县| 成都市| 剑川县| 桃园县| 八宿县| 遵义县| 吉水县| 昌图县| 邓州市| 桃园市| 全南县| 白水县| 来凤县| 渭源县| 德惠市| 浙江省| 雅安市| 昌吉市| 任丘市| 塔河县| 聂荣县| 资中县| 昂仁县| 精河县| 昭平县| 扶沟县| 炎陵县| 淳安县| 龙江县| 辽阳县| 新竹县| 大姚县| 来凤县| 沅陵县| 临安市| 阿瓦提县| 龙里县| 确山县| 黄骅市| 永德县|