delphi與彙編

我一直認爲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窗口跟蹤。
  OK!就談到這,但願對使用Delphi的朋友有點幫助編程

相關文章
相關標籤/搜索