一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

如何在DELPHI中使用匯編

 -飛龍在天- 2011-04-23
如何在DELPHI中使用匯編

出處:本站原創(chuàng) 作者:不詳 人氣:79 次 評論: 0 | 我要發(fā)表看法

DELPHI內(nèi)聯(lián)匯編好象有得天獨厚的優(yōu)勢,尤其是API的調(diào)用,處理好各成員參數(shù)后,可以直接CALL API名稱。利用內(nèi)聯(lián)匯編我們可以為程序添加各種異常,添加反調(diào)試代碼,添加花指令,還可以令某些難寫的注冊機簡單化等.我把DELPHI內(nèi)聯(lián)匯編的一點點使用心得寫出來,目的是想與大家交流,挖掘更多的這方面的領(lǐng)域。也希望大家能夠指正一些錯誤。


一、 數(shù)據(jù)格式
整型數(shù)據(jù):8位的用AL返回,16位的用AX返回,32位的用EAX返回。
BYTE(8位):BYTE、CHAR、SHORTINT、BOOLEAN
WORD(16位): SMALLINT、WORD
DWORD(32位):INTEGER、LONGWORD、ANSISTRING、POINTER、CLASS、LONGINT、STRING
ST(0):SINGLE、DOUBLE、EXTENDED、COM

如:
var
ByteVar: Byte;
WordVar: Word;
IntVar: Integer;
begin
asm
MOV AL,ByteVar
MOV BX,WordVar
MOV ECX,IntVar
end;
end;

實型:用ST(0)返回
  指針:用EAX返回
  長字符串:用EAX返回其所在地址
  變量:可用@Result返回

16進制的表示方式:
如果是0-9開頭的16進制值直接在后面加H或在前面加$號,如:1AH,$1A
如果是字母開頭的前面加0再在后面跟H,或者直接用$號,如:0AH,$A

幾個修飾符:
OFFSET 返回內(nèi)存地址中的立即數(shù)
[....] 返回內(nèi)存地址,與OFFSET相反,如:MOV EAX,OFFSET [XXXX]=MOV EAXX,[OFFSET XXXX]=MOV EAX,XXXX
HIGH 返回高8位的立即數(shù)
LOW 返回低8位的立即數(shù)
& 防止變量與匯編中的寄存器同名而在前面加& 號,如:
EAX:INTEGER; ...
MOV &EAX,10H 這里的&EAX不是EAX寄存器
. .號的一種用法:
var
STR: Word; ..
MOV DL,STR.Byte或DL,Byte(STR)


二、 嵌入式匯編的格式
  Delphi是使用ASM……END來標志匯編語句
   如:
ASM
   mov al,1
   mov bl,al
   END;

一個簡單加法函數(shù):
FUNCTION SUM(X,Y:INTEGER):INTEGER;
BEGIN
ASM
MOV EAX,X
ADD EAX,Y
MOV @RESULT,EAX
END;
END;

Byte轉(zhuǎn)換為16進制字符串:
function ByteToHex(Src: Byte): String;
begin
SetLength(Result, 2);
asm
MOV EDI, [Result]
MOV EDI, [EDI]
MOV AL, Src
MOV AH, AL // Save to AH
SHR AL, 4 // Output High 4 Bits
ADD AL, '0'
CMP AL, '9'
JBE @@OutCharLo
ADD AL, 'A'-'9'-1
@@OutCharLo:
AND AH, $f
ADD AH, '0'
CMP AH, '9'
JBE @@OutChar
ADD AH, 'A'-'9'-1
@@OutChar:
STOSW
end;
end;

三、 可用的寄存器
32位寄存器EAX EBX ECX EDX ESP EBP ESI EDI
 16位寄存器AX BX CX DX SP BP SI DI
 8位寄存器AL BL CL DL(低8位) AH BH CH DH(高8位)
 16位段寄存器CS DS SS ES
32位段寄存器 FS GS
 以及協(xié)處理器寄存器堆棧 ST
一個ASM statement 必須保護EDI,ESI,ESP,EBP和EBX寄存器,但是可以自由的修改EAX,ECX和EDX寄存器。
默認情況下,delphi使用“register”方式,若參數(shù)在3個以內(nèi), 將分別使用eax、edx和ecx,如果超過三個,則用堆棧傳遞。返回參數(shù)的存放視長度而定,例如8位用al返回,16位用ax,32位用eax,64位用用兩個32位寄存器edx:eax,其中eax是低位。如果你想用EBX寄存器,接得這樣寫:
asm
push ebx
mov ebx,2
mov IntVar,ebx
pop ebx
end;

如:FUNCTION(T1,T2,T3:INTEGER):INTEGER,可以默認為T1存在EAX中,T2存在EDX中,T3存在ECX中。
DELPHI的標簽名一般都以@開頭,比如@exit、@001等

四、 CALL的應(yīng)用
在匯編中寫代碼要保存寄存器現(xiàn)場(保存使用前的寄存器狀態(tài),使用Push壓棧和Pop從棧中彈出),不過這一切對于Delphi的嵌入式匯編是沒有必要的(除非你自己要使用Push和Pop),因為Delphi已經(jīng)幫你做了,不必擔(dān)心會使數(shù)據(jù)丟掉。
DELPHI內(nèi)聯(lián)匯編中同樣可以用匯編中CALL的功能。
比如:
asm
CALL @1
JMP @EXIT
@1:
MOV EAX,1
MOV SN,EAX
RETN
@exit:
end;

call的第二種用法,在匯編代碼中直接調(diào)用FUNCTION函數(shù),如:
function cacl(eax: integer):integer;
var
...
begin
....
Result:=code;
end;
調(diào)用時可以直接CALL CACL:
ASM
CALL CACL
...
END

編語句中的Call語句,可以用于調(diào)用其它過程,既可以是其它匯編程序段也可以是Delphi中的標準過程:
  例如:假設(shè)新建一個窗體并在上面加了一個按鈕,在Click事件中寫入以下代碼
  procedure TForm1.Button1Click(Sender: TObject);
  begin
   showmessage(`ok');
  end;
  再寫一個過程_X
  function TForm1._x(var i:smallint):integer;
  asm
   call button1click
  end;
  執(zhí)行_x的結(jié)果就可以顯示消息框。

五、調(diào)用API函數(shù)
DELPHI內(nèi)聯(lián)匯編中調(diào)用API函數(shù)函數(shù)非常簡單,比如調(diào)用PostQuitMessage:
Asm
Push 0
Call PostQuitMessage(或Call SYSTEM.PostQuitMessage)
End

調(diào)用MessageBox函數(shù):
procedure TForm1.Button2Click(Sender: TObject);
  var
   szTitle:string;
   szCaption:string;
  begin
   szTitle:='您好!';
   szCaption:='這是一個在內(nèi)嵌匯編中調(diào)用stdcall類型函數(shù)的例子.';
   asm
    PUSH MB_OK+MB_ICONINFORMATION
    PUSH szTitle
    PUSH szCaption
    PUSH 0
    CALL MessageBox
   end;
  end;

調(diào)用GetFileSize函數(shù)
function stdcalldemo: Integer;
var
FH: THandle;
begin
FH:= FileOpen(’c: oot.ini’,fmOpenRead);
asm
push 0
push FH
call GetFileSize
mov @Result,eax
end;
Result:= GetFileSize(FH,0);//此句就相當于上面的匯編調(diào)用方式
FileClose(FH);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(IntToStr(stdcalldemo));
end;

六、匯編的調(diào)試。
如果發(fā)現(xiàn)匯編通不過,就要注意停下后的位置的代碼:如變量的跟蹤、斷點、堆棧查看……可以在關(guān)鍵代碼處下斷,停下后打開View菜單的Debug Windows的CPU VIEW窗口,F(xiàn)8單步跟蹤。如:
Unit1.pas.62:     PUSH MB_OK+MB_ICONINFORMATION
00455E8F 6A40 push $40
Unit1.pas.63:     PUSH szTitle
00455E91 FF75FC push dword ptr [ebp-$04]
Unit1.pas.64:     PUSH szCaption
00455E94 FF75F8 push dword ptr [ebp-$08]
Unit1.pas.65:     PUSH 0
00455E97 6A00 push $00
Unit1.pas.66:     CALL MessageBox
00455E99 E8FA0DFBFF call MessageBox
Unit1.pas.69:   end;
00455E9E 33C0 xor eax,eax

七、常見易錯語句。
MOV ESI,DOWRD PTR SS:[TEXT] 對(TEXT為STRING)
MOV ESI,DOWRD PTR [TEXT] 對(段寄存器CS,DS,SS,ES可省略)
MOV AL,DOWRD PTR SS:[TEXT] 錯(DWORD為32位)
MOV AL,BYTE PTR [TEXT] 對
MOV EAX,BYTE PTR [TEXT] 錯(DWORD為8位)
MOV AL,WORD PTR [TEXT] 錯(DWORD為16位)
MOV EAX,WORD PTR [TEXT] 錯
MOV AX,WORD PTR [TEXT] 對
MOV [A],EAX
MOV BYTE PTR[EDI],'A'
MOV AL,[EDI]
MOV EAX,X //X指向的值賦值給EAX
MOV EAX,[EAX] //X指向的地址賦值給EAX
MOV DOWRD PTR[ESP],EAX 對
MOV DOWRD PTR[ECX],EAX 對
MOV DOWRD PTR[ECX+4],EAX 對
MOV DOWRD PTR[ECX+EDI],EAX 對
MOV DOWRD PTR[ESI],EAX 錯
MOV DOWRD PTR[EDX],EAX 錯
MOV DOWRD PTR[EBX],EAX 錯
.....

比較詳細的例子可以看一下
http://bbs./showthread.php?s=&threadid=26382
http://bbs./showthread.php?s=&postid=222986#post222986
里的注冊機代碼,更多的內(nèi)容還需要你補充…。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产一区麻豆水好多高潮| 久久午夜福利精品日韩| 精品欧美在线观看国产| 国产一区二区三区精品免费| 国产色偷丝袜麻豆亚洲| 国产剧情欧美日韩中文在线| 欧美韩日在线观看一区| 国产成人午夜在线视频| 亚洲一区二区三在线播放| 欧美日韩欧美国产另类| 日本亚洲精品在线观看| 国产精品久久久久久久久久久痴汉 | 爱在午夜降临前在线观看| 国产福利一区二区久久| 日本欧美在线一区二区三区| 在线欧美精品二区三区| 日本高清不卡在线一区| 激情爱爱一区二区三区| 国自产拍偷拍福利精品图片| 操白丝女孩在线观看免费高清| 日韩精品成区中文字幕| 国产av乱了乱了一区二区三区| 亚洲一区二区精品免费视频| 国产欧美一区二区三区精品视| 字幕日本欧美一区二区| 国产亚洲精品香蕉视频播放| 99久久人妻精品免费一区| 国产亚洲精品久久久优势| 国产av一区二区三区久久不卡| 丝袜人妻夜夜爽一区二区三区| 亚洲一区二区精品免费视频| 欧美国产日本高清在线| 欧美激情一区=区三区| 日韩欧美91在线视频| 日韩aa一区二区三区| 麻豆国产精品一区二区三区| 日本人妻熟女一区二区三区| 亚洲天堂精品1024| 亚洲欧美日韩在线看片| 国产av一区二区三区四区五区| 日系韩系还是欧美久久|