Delphi的嵌入式彙編 |
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
http://bbs.6to23.com/sys/show.asp?name=pchker&recno=135 關於:"DELPHI中彙編的調用? "
>
> wr960204 在 2002-10-4 19:03:10 提供了如下回答, 請您查閱和評估:
> --------------------------------------------------------------------------
> ---
> 我一直認?Delphi功能與C++相比毫不遜色,提供了豐富的控制項和類、全部API以及
> 嵌入的彙編。最近小弟在把C版的Huffman壓縮改用Delphi寫時,順便“研究”了一下
> Delphi的位操作和嵌入式彙編,利用嵌入彙編我們可以得到高效的程式碼,完成一
> 些Delphi沒有提供的底層功能。借貴報一方寶地與大家分享我的“研究”。
> Delphi的位操作
> 每個學習C的朋友都會被告之C是“中級語言”,其位元操作非常方便,而Pascal之
> 流只適用於教學。但是Delphi中提供了一組位操作,可別以過去對Pascal的態度看
> Delphi。
> * 按位元的邏輯操作:
> Delphi中的AND、OR、NOT可不僅僅只對邏輯運算式有作用,它們還可以運算元;
> AND:按位與,如:1 AND 2其結果?0
> OR:按位或,如:1 OR 2其結果?3
> Not:按位取反:如Not 1其結果對於有符號數是-2,對於無符號數是65534
> 另外,還有按位異或XOR:如:1 XOR 2結果?3
> * 移位操作
> Delphi提供了SHL和SHR進行移位左移和右移:
> 例如:2 SHR1表示2按位右移一位結果?1。
> * Delphi中的數
> 既然有位的操作就一定涉及到數的類型:是有符號數(頭一位元用0和1表示正負)
> 還是無符號數。
> Delphi中:Shortint(8位)、Smallint(16位)、Longint(32位)、Integer
> (32位)、Int64(64位元)是有符號數;而Byte(8位)、Word(16位)、Longword
> (32位元)是無符號數。它們之間可以像C一樣強制轉換。例如:Smallint類型的-1轉
> 換成Word類型就是65535。轉換方法是Word(-1)。
> 怎樣,夠全吧^_^!什?還不夠……!?Delphi還有一招,接招吧……
> Delphi的嵌入式彙編
> Delphi中提供了幾乎全部常用彙編指令的支援:MOV、JE、JMP、CMP、SHL、
> SHR、SAL、SAR、POP、PUSH、HLT……自己去查吧。至於INT也能識別,不過非法操作
> 或死機可別找我(在最早的Windows95中用Delphi 3似乎可以正確運行中斷,但
> Windows 95 OEM、Windows 98就不對了,大概是16位元模組的問題,還搞不清楚)。
> * 嵌入式彙編的格式
> Delphi是使用ASM……END來標誌彙編語句
> 如:ASM
> mov al,1
> mov bl,al
> END;
> * 可操作的寄存器
> Delphi可用彙編管理以下寄存器:
> 32位寄存器EAX EBX ECX EDX ESP EBP ESI EDI
> 16位寄存器AX BX CX DX SP BP SI DI
> 8位寄存器AL BL CL DL AH BH CH DH
> 16位段寄存器CS DS SS ES
> 以及輔助運算器寄存器堆疊 ST
> * 使用彙編前的工作
> 教彙編的老師一再強調使用彙編要保存寄存器現場(保存使用前的寄存器狀態,
> 使用Push壓棧和Pop從棧中彈出),不過這一切對於Delphi的嵌入式彙編是沒有必要
> 的(除非你自己要使用Push和Pop),因?Delphi已經幫你做了,不必擔心會使資料
> 丟掉。
> * Delphi嵌入式彙編的使用方式
> 1.在一般函數過程中使用彙編
> 組合語言程式段可以嵌套於其他過程中:如:
> procedure TForm1.Button1Click(Sender: TObject);
> var i:smallint;
> begin
> i:=1;
> asm
> mov ax,i
> sal ax,1
> mov &i,ax
> end;
> showmessage(inttostr(i));
> end;
> 這個程式段是把16位元的變數I進行左移,然後把結果用Mov &I,ax語句放入I變
> 量所在地址返回值。最後顯示I 的值是2。
> 2.獨立的組合語言程式段
> 組合語言程式段也可以單獨寫成函數或過程。這就涉及到參數的傳遞與結果的返回。
> 首先Delphi對於函數的返回有一個約定:
> 即:整型資料:8位的用AL返回,16位的用AX返回,32位的用EAX返回;
> 實型:用ST(0)返回
> 指標:用EAX返回
> 長字串:用EAX返回其所在地址
> 變數:可用@Result返回
> 例如:一個用彙編的求和函數
> function _Sum(X, Y: Integer): Integer;
> asm
> MOV EAX,X //把32位的數放入EAX
> ADD EAX,Y //進行加法運算
> MOV @Result,EAX //返回X+Y
> end;
> 一個把字元轉化?大寫的函數例子
> function _UpCase( ch : Char ) : Char;
> asm
> CMP AL,`a'
> JB @@exit
> CMP AL,`z'
> JA @@exit
> SUB AL,`a' -`A'
> @@exit:
> end;
> 值得注意的是第二個例子中,沒有象第一個那樣把參數用語句放到寄存器中,這
> 是由於Delphi中默認的把Byte(Char)類型放在AL中,不需要用Mov語句,但是這種函
> 數不能是類的成員,否則結果會出錯。
> 3.在彙編中調用其他過程
> 彙編語句中的Call語句,可以用於調用其他過程,既可以是其他組合語言程式段也可
> 以是Delphi中的標準過程:
> 例如:假設新建一個表單並在上面加了一個按鈕,在Click事件中寫入以下代碼
> procedure TForm1.Button1Click(Sender: TObject);
> begin
> showmessage(`ok');
> end;
> 再寫一個過程_X
> function TForm1._x(var i:smallint):integer;
> asm
> call button1click
> end;
> 執行_x的結果就可以顯示訊息方塊。
> * 彙編的調試
> 編好了程式,沒錯,還好,如果有錯,就得用到調試工具:如變數的跟蹤、斷
> 點、堆疊查看……對於彙編還可以用View功能表的Debug Windows的CPU視窗跟蹤。 ***************************************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |