91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

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

    巴塘县| 衡水市| 海盐县| 东安县| 聊城市| 多伦县| 铜梁县| 定南县| 化隆| 那曲县| 民勤县| 弋阳县| 紫云| 平度市| 襄樊市| 山丹县| 古浪县| 天气| 富裕县| 霍州市| 石楼县| 扎鲁特旗| 唐海县| 吕梁市| 刚察县| 伊川县| 鸡东县| 策勒县| 明溪县| 延庆县| 封开县| 万载县| 新和县| 鄱阳县| 西宁市| 淮安市| 那曲县| 廊坊市| 阿拉善左旗| 崇义县| 商丘市|