日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java函数调用约定_2020-09-04:函数调用约定了解么?

發布時間:2025/3/12 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java函数调用约定_2020-09-04:函数调用约定了解么? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

福哥答案2020-09-04:

初級回答:

stdcall和cdecl兩者的參數傳遞順序都是從右向左。

不同點是stdcall在被調用函數 (Callee) 返回前,由被調用函數 (Callee) 調整堆棧。cdecl在被調用函數 (Callee) 返回后,由調用方 (Caller) 調整堆棧,每一個調用它的函數都包含清空堆棧的代碼,所以產生的可執行文件大小會比調用_stdcall函數的大。

中級回答:

1.__stdcall

在被調用函數 (Callee) 返回前,由被調用函數 (Callee) 調整堆棧

參數從右向左壓入堆棧。

函數名自動加前導的下劃線,后面緊跟一個@符號 ,其后緊跟著參數的尺寸。

2.__cdecl

在被調用函數 (Callee) 返回后,由調用方 (Caller) 調整堆棧。

函數實參在線程棧上按照從右至左的順序依次壓棧。

函數結果保存在寄存器EAX/AX/AL中

浮點型結果存放在寄存器ST0中

編譯后的函數名前綴以一個下劃線字符

調用者負責從線程棧中彈出實參(即清棧)

8比特或者16比特長的整形實參提升為32比特長。

受到函數調用影響的寄存器(volatile registers):EAX, ECX, EDX, ST0 - ST7, ES, GS

不受函數調用影響的寄存器: EBX, EBP, ESP, EDI, ESI, CS, DS

RET指令從函數被調用者返回到調用者(實質上是讀取寄存器EBP所指的線程棧之處保存的函數返回地址并加載到IP寄存器)

3.__fastcall

__fastcall調用的主要特點就是快,因為它是通過寄存器來傳送參數的。

實際上__fastcall用ECX和EDX傳送前兩個DWORD或更小的參數,剩下的參數仍自右向左壓棧傳送,被調用的函數在返回前清理傳送參數的內存棧。

__fastcall調用約定在輸出函數名前加上一個“@”符號,后面也是一個“@”符號和其參數的字節數,格式為@function @number ,如double multi(double a, double b)的修飾名是@multi@16。

__fastcall和__stdcall很象,唯一差別就是頭兩個參數通過寄存器傳送。注意通過寄存器傳送的兩個參數是從左向右的,即第1個參數進ECX,第2個進EDX,其他參數是從右向左的入棧,返回仍然通過EAX。

fastcall調用約定和stdcall類似,它意味著:

函數的第一個和第二個DWORD參數(或者尺寸更小的)通過ecx和edx傳遞,其他參數通過從右向左的順序壓棧;

被調用函數清理堆棧;

函數名修改規則同stdcall。

Fast Calling Convention,快速調用約定。通過使用寄存器解決效率問題。特點:

函數參數部分通過寄存器傳遞,函數中最左的兩個DWORD(寄存器大小是雙字)或者更小的參數,通過寄存器傳遞。剩下的從右到左堆棧傳遞。 函數名改編:“@函數名@函數參數字節大小十進制”。 返回方式同__stdcall。

4.__thiscall

thiscall是唯一一個不能明確指明的函數修飾,因為thiscall不是關鍵字。它是C++類成員函數缺省的調用約定。由于成員函數調用還有一個this指針,因此必須特殊處理,thiscall意味著:

參數從右向左入棧;

如果參數個數確定,this指針通過ecx傳遞給被調用者;如果參數個數不確定,this指針在所有參數壓棧后被壓入堆棧;

對參數個數不定的,調用者清理堆棧,否則函數自己清理堆棧。

主要用于解決this指針問題,使用寄存器傳遞this指針。返回方式同__stdcall.

5.__nakedcall

這是一個很少見的調用約定,一般程序設計者建議不要使用。編譯器不會給這種函數增加初始化和清理代碼,更特殊的是,不能用return返回返回值,只能用插入匯編返回結果。

6.__pascal

基于Pascal語言的調用約定,參數從左至右入棧(與cdecl相反)。被調用者負責在返回前清理堆棧。 此調用約定常見在如下16-bit 平臺的編譯器:OS/2 1.x,微軟Windows 3.x,以及Borland Delphi版本1.x。

7.__vectorcall

目的是用來優化浮點向量運算,intel處理器種有很多浮點向量寄存器,傳統的調用約定(stdcall cdecl fastcall thiscall) 都是通過通用寄存器(ecx edx /rcx rdx r8 r9)以及堆棧進行參數傳遞,所以調用的時候,浮點參數需要從棧獲取。

要求盡可能在寄存器中傳遞參數。函數名改編為”@@函數名@參數字節數十進制”。這是微軟自己添加的標準。

8.syscall

與cdecl類似,參數被從右到左推入堆棧中。EAX, ECX和EDX不會保留值。參數列表的大小被放置在AL寄存器中(?)。 syscall是32位OS/2 API的標準。

9.optlink

參數也是從右到左被推入堆棧。從最左邊開始的三個字符變元會被放置在EAX, EDX和ECX中,最多四個浮點變元會被傳入ST(0)到ST(3)中----雖然這四個參數的空間也會在參數列表的棧上保留。函數的返回值在EAX或ST(0)中。保留的寄存器有EBP, EBX, ESI和EDI。 optlink在IBM VisualAge編譯器中被使用。

10.__clrcall

__clrcall是C++ .Net里面的。

總結

以上是生活随笔為你收集整理的java函数调用约定_2020-09-04:函数调用约定了解么?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。