Delphi + Asm - TBits类的学习

技术交流,DH讲解.

在D2010的classes中有个TBits类,这个类主要是位操作的.

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;这个属性,就是读取和设置某一位的.
那我们看看它是怎么实现的?

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中有多少个一么?
当时我们用的方法是移位然后与,那么我们现在换个方法呢?

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.

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

你可能感兴趣的:(Delphi + Asm - TBits类的学习)