函式的返回值儲存在記憶體的什麼區域

2022-06-26 22:39:21 字數 1618 閱讀 4744

函式的返回值儲存在記憶體的什麼區域呢?

1、結構體大小不超過4位元組,那麼仍然使用eax暫存器傳遞返回值

2.結構體超過4位元組但不等於8位元組時,呼叫者將首先在棧上分配一塊能容納結構體的臨時記憶體塊,然後在傳遞完函式引數後將該臨時記憶體塊的首位址作為隱含的第乙個引數最後(因為壓棧順序是從右到左)壓棧,接下的動作同前所述。當被呼叫函式返回時,它會通過第乙個隱含引數定址到臨時記憶體塊並將返回值拷貝到其中,然後將儲存有返回值內容的臨時記憶體塊的首址存進eax暫存器中,

3、結構體大小剛好為8個位元組時編譯器不再於棧上分配記憶體,而直接同時使用eax和edx兩個暫存器傳遞返回值,其中eax儲存低4位元組資料,edx儲存高4位元組資料。

函式在定義時,必有其返回型別,返回型別可以為數值型(指標是表示位址的數值),void型別。函式只能返回乙個值,數值形式可以是4位元組的整型,浮點,8位元組大小的long long,還可以返回結構體型別。雖然返回的都是數值,但是其中的返回機制不同。

函式的區域性變數定義在棧中,棧的特點後進先出(lifo)。區域性變數所在的棧的高位址在下,低位址在上。從main開始,申請變數時棧頂指標向上移動,進入區域性變數,區域性變數的申請同在main函式中一樣,一旦子函式執行完畢,則棧頂指標下移到進入區域性變數時的位置,子函式所申請的區域性變數空間都被**。所以如果函式需要子函式中的一些值時,可以通過返回該資料來獲得(用指標間接訪問變數無需返回)。

1)討論整型,浮點型,指標等4位元組大小的數值。

int add(int x,int y)

int main()

該函式返回部分的彙編**:

return z;

001813f7 8b 45 f8             mov         eax,dword ptr [z] 

return這一段中,可以看到z中計算好的資料移到eax暫存器中,由eax暫存器將值帶給呼叫該函式的函式變數。

在返回這些型別時,系統將該函式所要返回的值移到暫存器中,棧頂指標下移,棧中的區域性變數都死亡,暫存器中的資料再返回給呼叫該函式的函式所要接收的變數。

2)討論longlong等8位元組大小的數值。

在32bit的編譯環境中,eax暫存器一次性只能接受傳遞4位元組大小的資料,而8位元組的大小顯然靠它一次性是不能完全拿到的。

**為將上述的int改為long long型別。

函式返回部分的彙編**:

return z;

000c1400 8b 45 f4             mov         eax,dword ptr [z]  

000c1403 8b 55 f8             mov         edx,dword ptr [ebp-8]  

該函式的返回機制與4位元組的相似,只是由兩個暫存器來返回該值,其中將long long位元組分為兩部分移到eax和edx兩個暫存器,通過這兩個暫存器將函式值返回。

3)返回結構體型別的資料

乙個結構體變數中可以包含多個不同資料變數,其大小很容易超過8位元組,如果靠多個暫存器來實現將值帶回到呼叫函式中,很不現實。

函式舉例:

typedef struct student;

student test()

int main()

該函式的返回型別為student結構體型別,該型別的大小為28位元組。

函式返回部分的彙編**:

函式的返回值儲存在記憶體的什麼區域

1 結構體大小不超過4位元組,那麼仍然使用eax暫存器傳遞返回值 2.結構體超過4位元組但不等於8位元組時,呼叫者將首先在棧上分配一塊能容納結構體的臨時記憶體塊,然後在傳遞完函式引數後將該臨時記憶體塊的首位址作為隱含的第乙個引數最後 因為壓棧順序是從右到左 壓棧,接下的動作同前所述。當被呼叫函式返回...

C 中函式返回值的儲存

在c 中,可以使用多種方式返回乙個變數 物件 比如直接返回乙個臨時物件 返回其引用 返回其指標。配合不同的修飾符,又可能產生不同的效果。下面我在visualstudio2013中測試了一下什麼樣的儲存方式是合法的,什麼樣的儲存方式是非法的。為了防止編譯器優化影響結果,我在被呼叫的函式中使用了標準輸入...

函式的返回值

函式並非總是直接顯示輸出,相反,它可以處理一些資料,並返回乙個或一組值,函式返回的值被稱為返回值 在函式中,可使用return 語句將值返回到呼叫函式的 行。返回值讓你能夠將程式的大部分繁重工作移到函式中去完成,從而簡化主程式 函式可返回任何型別的值,包括列表和字典等較複雜的資料結構 函式的返回值就...