進幾天一直在研究在delphi中使用彙編的問題。上回說了一點。今天再把我剛剛弄出來的一點東西寫上來。
EBP、ESP、BP和SP都稱為指針寄存器,主要用于存放堆棧記憶體儲單元的偏移量,用它們可實作多種存儲器操作數的尋址方式。
現在我們來說一說EBP:
EBP是基址指針寄存器:一般用來确認堆棧幀的起始位置,也就是指向棧底。也就是說,一般一個函數入口的位址也就存放在EBP中(是以一般在進入函數的時候将ebp寄存器内容壓棧,即儲存其函數的上級調用函數的棧基位址,以便于以後傳回調用)。
比如,我們要實作點一個Form1上的按扭Button1實作彈出對話框。我們一般是
procedure TForm1.Button1Click(Sender: TObject);
var ss: string;
begin
ss := '不得閑BASM測試';
showmessage(ss);
end;
那麼換成彙編的寫法如下:
asm
mov eax,[ebp-04]callshowmessageend;end;//說明:Ebp通過上面我們知道應該是用來指定Button1Click過程的入口位址,将其減4用來空一點空間出來用來存放局部變量,則此時[ebp−04]中存放的則是字元串ss的位址,是以此時eax中存放的則是′BASM測試′的位址然後CallShowmessage,調用Showmessage函數,而Delphi預設的調用方式是寄存器方式,其1,2,3個參數分别對應着EAX,EDX,ECX,而EAX中已經存放了我們的局部變量位址。該函數則獲得了字元串參數。上面的是用在過程裡面,直接使用指派後的字元串的位址傳遞給Showmessage函數調用。下面我們使用另一個方法來使用局部變量:通過檢視CPUView我們可以知道,在上面的字元串指派過程的彙編代碼如下:leaeax,[ebp−04]callshowmessageend;end;//說明:Ebp通過上面我們知道應該是用來指定Button1Click過程的入口位址,将其減4用來空一點空間出來用來存放局部變量,則此時[ebp−04]中存放的則是字元串ss的位址,是以此時eax中存放的則是′BASM測試′的位址然後CallShowmessage,調用Showmessage函數,而Delphi預設的調用方式是寄存器方式,其1,2,3個參數分别對應着EAX,EDX,ECX,而EAX中已經存放了我們的局部變量位址。該函數則獲得了字元串參數。上面的是用在過程裡面,直接使用指派後的字元串的位址傳遞給Showmessage函數調用。下面我們使用另一個方法來使用局部變量:通過檢視CPUView我們可以知道,在上面的字元串指派過程的彙編代碼如下:leaeax,[ebp−04]{這是留出一個空位,用來給局部變量中轉使用}
mov edx, 2342342這裡是一個随機的值,也就是字元串指針的值然後下面調用了一個系統函數LstrLAsgCallLstrLAsg該函數将EDX指向的位址内容複制到EAX指向的位址中去。是以由此可見,Delphi中的字元串指派是通過拷貝實作的。是以我們可以通過一個過程傳遞一個字元串位址值來得實作上面的方法,代碼如下:procedureTest(prAddress:integer);asmmovedx,eax//先将prAddress位址值存入Edx,便于調用LstrLAsg函數leaeax,[ebp−2342342這裡是一個随機的值,也就是字元串指針的值然後下面調用了一個系統函數LstrLAsgCallLstrLAsg該函數将EDX指向的位址内容複制到EAX指向的位址中去。是以由此可見,Delphi中的字元串指派是通過拷貝實作的。是以我們可以通過一個過程傳遞一個字元串位址值來得實作上面的方法,代碼如下:procedureTest(prAddress:integer);asmmovedx,eax//先将prAddress位址值存入Edx,便于調用LstrLAsg函數leaeax,[ebp−04] //将使用一個局部變量周轉,(偏移位址)
Call System.@LstrLAsg //調用系統的LstrLAsg函數實作字串複制
mov eax, [ebp-$04] //将實際的局部變量位址傳遞給Eax讓Showmessage調用
Call Showmessage //調用Showmessage函數
end;
然後我們在ButtonClick中調用如下:
procedure TForm1.Button1Click(Sender: TObject);
Test(integer(ss));
end;
本文轉自 不得閑 部落格園部落格,原文連結:http://www.cnblogs.com/DxSoft/archive/2010/01/01/1637648.html ,如需轉載請自行聯系原作者