Delphi代碼中嵌入ASM代碼(簡單明瞭)

前言

  Delphi做爲一個快速高效的開發平臺,使用的人愈來愈多,但熟悉在Delphi代碼中嵌入ASM代碼的程序員我想很少,由於這方面的資料太少了,另外一方面,它還須要有基本的彙編語言知識,關於彙編語言的教程,那實在太多了,若是你對彙編語言不熟的話,建議你下載相交的教程先讀讀。所以,本文假定您已經熟悉了彙編語言。
  (注,下文中的函數與過程統稱爲函數。)


一.如何在Delphi程序中增長一段彙編代碼?
  很簡單,用asm...end把你的彙編代碼封裝起來,再把它放到你須要它的位置.這個須要它的位置能夠是函數的begin與end之間,也能夠是Program的begin與end之間,固然,好能夠是initialization與end之間或finalization與end之間,一句話,任何能夠放Delphi執行代碼的地方。
  
  範例1:對變量X實現邏輯循環右移8位,它告訴您如何在過程程中插入一段asm代碼。

  procedure Tform1.Button1Click(Sender: TObject);
  var
   X:DWORD;
  begin
   X:=$FF000000;
   ShowMessage(format('移位前: %.8X',[X]));
   asm
    MOV EAX, X
    ROR EAX, 8
    MOV X, EAX
   end;
   ShowMessage(format('移位後: %.8X',[X]));
  end;

  怎麼樣,是否是很簡單? 

二.如何在彙編代碼中調用函數?

  首先,須要講一下函數的調用方式。

  在Delphi中,函數的調用方式有五種,分別是register,pascal,cdecl,stdcall以及safecall,最經常使用的是register及stdcall方式.如何區別這五種方式,它們之間依據三個方面來區分,第一是參數傳遞順序(Parameter Order),第二是堆棧清除方(Clean-up),第三是是否以寄存器來傳遞參數(Passes parameters in registers?).您能夠在Delphi Help中找到相關資料。

  Delphi中默認的參數傳遞方式是register,即不加方式聲明的狀況下,都是register方式.register方式的參數傳遞順序是從左到右,由被調用者來清除堆棧,而且使用寄存器來傳遞參數。如何使用寄存器來傳遞參數呢?第一個參數使用EAX,第二個參數使用EDX,第三個參數使用ECX,第四個及之後的參數使用堆棧來傳遞,而且這些使用堆棧的參數是從左到右入棧的。

  stdcall是Windows的默認參數傳遞方式,它不使用寄存器來傳遞參數,這種方式下參數的傳遞順序是從右到左,即最後一個參數第一個入棧,依次向前,按倒序入棧。

  範例2:用asm代碼調用MessageBox函數,它告訴您如何在asm中調用stdcall方式的函數。
  procedure Tform1.Button2Click(Sender: TObject);
  var
   sztitle:string;
   szCaption:string;
  begin
   sztitle:='您好!';
   szCaption:='這是一個在內嵌彙編中調用stdcall類型函數的例子.';
   asm
    PUSH MB_OK+MB_ICONINformATION
    PUSH sztitle
    PUSH szCaption
    PUSH 0
    CALL MessageBox
   end;
  end;

  先來看看MessageBox函數的聲明:
    function MessageBox(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
  這個函數的調用方式是stdcall,參數必須從右到左入棧,因此咱們先將uType參數入棧,範例中該參數的值是MB_OK+MB_ICONINformATION,即PUSH MB_OK+MB_ICONINformATION,而後再將lpCaption,lpText,hWnd依次入棧.最後才使用CALL指令調用MessageBox函數。

  範例3:用asm代碼調用register方式的函數.StrLen的聲明爲:function StrLen(const Str: PChar): Cardinal; 它的調用方式是默認的register方式.
  procedure Tform1.Button3Click(Sender: TObject);
  var
   Str:PChar;
   iLen:Integer;
  begin
   Str:='abcdefghijklm';
   asm
    MOV EAX, Str    //用EAX傳遞第一個參數
    CALL StrLen
    MOV iLen,EAX
   end;
   ShowMessage(IntToStr(iLen));
  end;

http://websoso.bokee.com/4693792.htmlhtml

http://blog.csdn.net/yanjiaye520/article/details/6285267程序員

相關文章
相關標籤/搜索