Delphi + Asm - TBits類的學習

技術交流,DH講解.html

在D2010的classes中有個TBits類,這個類主要是位操做的.ide

1
2
3
4
5
6
7
8
9
10
11
12
13
14
TBits = class
private
   FSize: Integer ;
   FBits: Pointer ;
   procedure  Error;
   procedure  SetSize(Value: Integer );
   procedure  SetBit(Index: Integer ; Value: Boolean );
   function  GetBit(Index: Integer ): Boolean ;
public
   destructor  Destroy; override;
   function  OpenBit: Integer ;
   property  Bits[Index: Integer ]: Boolean  read GetBit write  SetBit; default;
   property  Size: Integer  read FSize write  SetSize;
end ;

這個類沒有什麼方法,咱們看到了property Bits[Index: Integer]: Boolean read GetBit write SetBit; default;這個屬性,就是讀取和設置某一位的.
那咱們看看它是怎麼實現的?oop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//在類中Eax就是Self指針
procedure  TBits . SetBit(Index: Integer ; Value: Boolean ); assembler;
asm
         CMP     Index,[EAX].FSize  //若是Indx>=Size then 擴容
         JAE     @@Size
 
@@ 1 :    MOV     EAX,[EAX].FBits
         OR       Value,Value
         JZ      @@ 2
         BTS     [EAX],Index  //將Eax中第Index位賦值給CF,而後Eax第index位=1;
         RET
 
@@ 2 :    BTR     [EAX],Index //將Eax中第Index位賦值給CF,而後Eax第index位=0;
         RET
 
@@Size: CMP     Index, 0    //if index <0 then Error
         JL      TBits . Error
         PUSH    Self      //push [eax]
         PUSH    Index
         PUSH    ECX {Value}
         INC     Index
         CALL    TBits . SetSize
         POP     ECX {Value}
         POP     Index
         POP     Self
         JMP     @@ 1
end ;
 
function  TBits . GetBit(Index: Integer ): Boolean ; assembler;
asm
         CMP     Index,[EAX].FSize
         JAE     TBits . Error
         MOV     EAX,[EAX].FBits
         BT      [EAX],Index   //將eax的第Index位賦值給CF
         SBB     EAX,EAX //eax - (eax + CF)
         AND      EAX, 1   //清除Eax中的其餘位
end ;

這裏咱們發現BTR,BTS,BT,SBB等位操做符.咱們以前不是算過99999中有多少個一麼?
當時咱們用的方法是移位而後與,那麼咱們如今換個方法呢?spa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Function  _1Bits(ANum: Integer ): Integer ;
asm
   xor  edx,edx // 位數
   xor  ecx,ecx // 1的個數
@@nLoop:
   cmp edx, 32   // 循環32次
   je @@nExit
   bt eax,edx
   jnc @@nNoInc // if CF = 0 then
   inc ecx
@@nNoInc:
   inc edx
   jmp @@nLoop
@@nExit:
   mov eax,ecx
end ;

所有都是直接對位操做的.
BTR和BTS的做用如上面我註釋中寫的那樣,可是我如今沒有其餘例子給你們看.TBits類很純潔,因此能夠用到其餘版本中去.指針

我是DH.code

http://www.cnblogs.com/huangjacky/archive/2010/01/19/1651359.htmlhtm

相關文章
相關標籤/搜索