【软件开发底层知识修炼】二十五 ABI之函数调用约定二之函数返回值为结构体时的约定
- 上一篇文章學(xué)習(xí)了幾種函數(shù)調(diào)用約定的區(qū)別,點擊鏈接查看上一篇文章:【軟件開發(fā)底層知識修煉】二十四 ABI之函數(shù)調(diào)用約定
- 本篇文章繼續(xù)學(xué)習(xí)函數(shù)調(diào)用約定中,關(guān)于函數(shù)返回值的問題。當(dāng)函數(shù)返回值為結(jié)構(gòu)體時,函數(shù)返回值是如何來傳給調(diào)用者的。
文章目錄
- 1 函數(shù)返回值為結(jié)構(gòu)體類型
- 1.1 函數(shù)返回值用于初始化變量
- 1.2 函數(shù)返回值給變量賦值
- 2 代碼案例分析
- 3 總結(jié)
1 函數(shù)返回值為結(jié)構(gòu)體類型
前一篇文章我們學(xué)習(xí)了當(dāng)函數(shù)的返回值是整形時,函數(shù)返回時,如何將返回值傳遞給調(diào)用者。是通過eax寄存器來傳遞的。
但是當(dāng)返回值為結(jié)構(gòu)體時,eax寄存器顯然存不下結(jié)構(gòu)體。那么該如何將返回值傳遞給調(diào)用者呢?
- 函數(shù)調(diào)用時,用來接收函數(shù)返回值的結(jié)構(gòu)體變量的地址需要入棧。
- 然后被調(diào)用函數(shù)直接通過該結(jié)構(gòu)體變量的地址,將返回值拷貝過去
但是有一點要注意,就是函數(shù)返回值用于初始化以及用于賦值時,這兩個過程,內(nèi)部的調(diào)用約定是不一樣的。參考下面。
1.1 函數(shù)返回值用于初始化變量
上述圖示的過程還是很簡單的,當(dāng)函數(shù)返回值作為其他變量的初始值的時候:
- 首先將變量的地址入棧
- 當(dāng)函數(shù)返回時,將返回值拷貝到變量st的地址處即可
1.2 函數(shù)返回值給變量賦值
上述圖示與11節(jié)內(nèi)容不太一樣。當(dāng)函數(shù)返回值是給一個變量賦值而不是初始化的時候:
- 首先生成一個臨時的變量temp,將temp地址入棧
- 然后當(dāng)函數(shù)返回時,將返回值拷貝到這個臨時變量的地址處
- 最后再將臨時變量的值賦值給st
可以看到,當(dāng)函數(shù)返回值作為其他變量的初始值時只需要一次的數(shù)據(jù)拷貝,但是當(dāng)函數(shù)返回值給其他變量賦值時,卻是兩次的數(shù)據(jù)拷貝。所以在平時的代碼中,盡量都是直接將函數(shù)返回值作為初始值,而盡量不要將返回值以賦值的形式給其他變量以免造成不必要的開銷。
2 代碼案例分析
本來是想將實驗過程寫清楚的,但是想想,這個代碼的調(diào)試過程還是留給讀者吧。畢竟我前面寫的二十幾篇都是將完整的步驟寫出來了,如果學(xué)會了前面gdb調(diào)試的內(nèi)容那么自己調(diào)試應(yīng)該不在話下。我只給出調(diào)試的思路和代碼。
- 代碼:
return.c
#include <stdio.h>struct ST {int x;int y;int z; };struct ST f(int x, int y, int z) {struct ST st = {0};printf("f() : &st = %p\n", &st);st.x = x;st.y = y;st.z = z;return st; }void g() {struct ST st = {0};printf("g() : &st = %p\n", &st);st = f(1, 2, 3);printf("g() : st.x = %d\n", st.x);printf("g() : st.y = %d\n", st.y);printf("g() : st.z = %d\n", st.z); }void h() {struct ST st = f(4, 5, 6);printf("h() : &st = %p\n", &st);printf("h() : st.x = %d\n", st.x);printf("h() : st.y = %d\n", st.y);printf("h() : st.z = %d\n", st.z); }int main() {h();g();return 0; }調(diào)試思路:使用gdb進(jìn)行調(diào)試。在不同的函數(shù)棧幀中查看當(dāng)前函數(shù)棧幀中,結(jié)構(gòu)體變量的地址是否入棧或者是否有一個臨時變量的地址入棧。然后通過使用gdb打斷點的形式,證明最終函數(shù)返回時是將返回值拷貝到相應(yīng)的地址。當(dāng)然,最后最干脆的方法還是查看該程序的反匯編代碼,通過閱讀反匯編代碼來更加清晰的認(rèn)識整個函數(shù)的運行機制。
好了,這次就不寫調(diào)試步驟了,有心的人可以自己調(diào)試哦~
3 總結(jié)
學(xué)會了
- 函數(shù)返回值為結(jié)構(gòu)體的時候,如何將返回值傳遞給調(diào)用者
- 函數(shù)返回值作為初始化與賦值時的不同。注意效率問題
總結(jié)
以上是生活随笔為你收集整理的【软件开发底层知识修炼】二十五 ABI之函数调用约定二之函数返回值为结构体时的约定的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stata15中文乱码_一次性解决Sta
- 下一篇: IT信息化厂商