Delphi 調侃呼叫方式

2022-02-18 04:21:03 字數 2942 閱讀 9932

技術交流,dh講解.

本隨筆,就自己一心得+筆記,而自己水平有限,所以本文也可能是水文.哈哈

講解前先來個**:有條件的朋友可以看加密解密(第三版)一書,哈哈,我書還是買了一些的.

方式傳值方向

傳值位置

誰來平衡堆疊

備註 _cdecl

從右到左

直接壓棧

呼叫者預設c++的

_stdcall

從右到左

直接壓棧

函式本身

win32 api

register

從左到右

adc暫存器然後壓棧

函式本身

delphi預設的

pascal

從左到右

直接壓棧

函式本身

safecall

同stdcall

不同呼叫有什麼區別呢?

function teststdcall(a,b:integer):integer ;stdcall;

var c:integer;

begin

c:=a+b;

if c>2*a then

dec(c,b)

else

dec(c,a);

result:=c;

end;

function testcdecl(a,b:integer):integer ;cdecl;

var c:integer;

begin

c:=a+b;

if c>2*a then

dec(c,b)

else

dec(c,a);

result:=c;

end;

function testregister(a,b:integer):integer ;

var c:integer;

begin

c:=a+b;

if c>2*a then

dec(c, b)

else

dec(c, a);

result:= c;

end;

procedure tform4.formcreate(sender: tobject);

var c: integer;

begin

c:= teststdcall(5, 6);

showmessage(inttostr(c));

c:= testcdecl(5, 6);

showmessage(inttostr(c));

c:= testregister(5, 6);

showmessage(inttostr(c));

end;

**都一樣,我們來看看執行時候有什麼不一樣的地方呢?

第乙個teststdcall:

我們看見先壓6再壓5,也就是從右到左壓棧.函式內部:

先將棧裡面的引數取出來放到ecx和edx中,最後清除棧ret 8;

stdcall很明顯了.

接下來看cdecl呼叫方式吧.

也是先壓6再壓5,但是我們看到最後面add esp,8,這個就是平衡棧了,因為我們壓入了2個integer,8個位元組.

函式內部:

還是先從棧裡面去引數到暫存器,最後直接ret咯.

接下來是delphi預設的方式:

將5傳入eax,6傳入edx,它這裡雖然現傳的6,但是我們要注意暫存器的順序應該是 eax,edx,ecx,如果還有多餘的引數再壓棧.

函式內部:

暈這個例子沒有選好,因為引數沒有用到棧,所以不存在棧平衡,我改一下...

從壓棧的順序我們再一次看出來了,是從左到右的,先壓的8.

釋放引數壓棧用的空間,ret 8;

最後改一下,來看看pascal呼叫方式,這個是delphi1.0時候用的:

從左到右壓棧的.

細心的朋友會發現這次沒有講棧裡面東西取到暫存器中去,主要因為這次運算太簡單了.哈哈,最後自己清除壓的棧.

為什麼要了解這些?

答案肯定是為了程式能夠正常的工作了.這個問題...

如果宣告和呼叫的方式不一樣會怎麼樣?

1 走錯路.如果只是從左到右和從右到左弄錯了,程式能執行,只是引數a被當成引數b來用,也就是結果可能不對.

2 走上不歸路.因為我們知道堆疊裡面儲存了函式的返回位址這些,但是如果我們呼叫方式不一樣就可能造成堆疊被破壞了,程式無法正常返回,就會報錯了.

ok,個人理解.

delphi 呼叫dll兩種方式

1 外部宣告 在delphi中外部宣告是訪問外部例程最容易和最常用的方式,有兩種宣告方式 通過名字 通過索引號。舉例如下 在mydll.dll中有兩個函式和乙個過程,則其外部宣告可以寫成 function test1 integer external mydll 直接通過名稱呼叫test1 注意名稱...

delphi呼叫webservice服務

我用delphi的thttprio控制項呼叫了c 寫的webservice。下面是我除錯時遇到的一些問題 注意末尾的 wsdl 不能少。要不可能會說找不到。2,設定thttprio控制項的屬性 開始把賦給了wsdllocation屬性。連線時總是報錯。後來賦給url屬性,就不報錯了。3,傳遞引數是w...

DELPHI儲存過程呼叫

網上對該問題的帖子很多,但是經常不是很全面,筆者在使用時也遇到了很多實際問題,比如引數不存在啊 型別沒有引用啊等等。下面我盡量細緻地來通過例子實現一下,如果還有不正確的地方,希望得到高手指點,有興趣的可以和我一同 zyf0808 yeah.net 首先,我們使用一種簡單的方式,即通過控制項的方式來定...