技術交流,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