unit unit1
;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ,
Dialogs, StdCtrls ;
type
TForm1 = class(TForm )
Button1: TButton ;
Memo1: TMemo ;
procedure Button1Click(Sender: TObject );
private
{ Private declarations }
public
{ Public declarations }
end ;
var
Form1: TForm1 ;
implementation
{$R *.dfm}
const
HexStr: String = 'ABCD1234' ;
CalcTimes: Integer = 1000000 ;
type
THexToIntFunc = function(const S: String): DWORD ;
function HexToInt_tseug0(const S: String): DWORD ;
asm
PUSH EBX
PUSH ESI
MOV ESI, EAX //字符串地址
MOV EDX, [EAX-4] //读取字符串长度
XOR EAX, EAX //初始化返回值
XOR ECX, ECX //临时变量
TEST ESI, ESI //判断是否为空指针
JZ @@2
TEST EDX, EDX //判断字符串是否为空
JLE @@2
MOV BL, $20
@@0:
MOV CL, [ESI]
INC ESI
OR CL, BL //如果有字母则被转换为小写字母
sub CL, '0'
JB @@2 // < '0' 的字符
CMP CL, $09
JBE @@1 // '0'..'9' 的字符
sub CL, 'a'-'0'-10
CMP CL, $0A
JB @@2 // < 'a' 的字符
CMP CL, $0F
JA @@2 // > 'f' 的字符
@@1: // '0'..'9', 'A'..'F', 'a'..'f'
SHL EAX, 4
OR EAX, ECX
DEC EDX
JNZ @@0
JMP @@3
@@2:
XOR EAX, EAX // 非法16进制字符串
@@3:
POP ESI
POP EBX
RET
end ;
function HexToInt_tseug1(const S: String): DWORD ;
var
I : Integer ;
begin
Result := 0 ;
for I := 1 to Length(s) do
begin
case s[I] of
'0'..'9': Result := Result * 16 + Ord(S[I]) - Ord('0' );
'A'..'F': Result := Result * 16 + Ord(S[I]) - Ord('A') + 10 ;
'a'..'f': Result := Result * 16 + Ord(S[I]) - Ord('a') + 10 ;
else
Result := 0 ;
Exit ;
end ;
end
end ;
function HexToInt_DoubleWood(const S: string): DWORD ;
const
Convert: array[0..255] of Integer =
(
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 ,
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,- 1
);
var
I: Integer ;
v: Integer ;
begin
Result := 0 ;
if Pointer(s) = nil then exit ;
for I := 1 to PInteger(Integer(s) - 4)^ do
begin
begin
V := Convert[ord(s[i ])];
if V<0 then
begin
Result := 0 ;
Exit ;
end ;
result := (result * 16) or V ;
end ;
end ;
end ;
function HexToInt_beta1(const S: string): DWORD ;
const
ValidateTbl: array [0..255] of Byte = (
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 16, 16, 16, 16, 16, 16 ,
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 );
asm
push ebx
push ecx
push edx
push esi
push edi
mov esi, eax //字符串地址
mov ecx, [eax-4] //读取字符串长度
test esi, esi //判断是否为空指针
jz @Err
test ecx, ecx //判断字符串是否为空
jle @Err
xor eax, eax
lea edi, ValidateTbl
mov edx, ecx
xor ebx, ebx
@LoopValidate:
mov bl, [esi]
mov bl, [edi][ebx]
test ebx, 16
jnz @Err
shl eax, 4
or eax, ebx
inc esi
dec edx
jnz @LoopValidate
jmp @Ext
@Err:
xor eax, eax // 非法16进制字符串
@Ext:
pop edi
pop esi
pop edx
pop ecx
pop ebx
end ;
function HexToInt_beta2(const S: string): DWORD ;
const
ValidateTbl: array [0..255] of Byte = (
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 16, 16, 16, 16, 16, 16 ,
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 );
asm
push ebx
push ecx
push edx
push esi
push edi
mov edi, esp
push 0
mov esi, eax //字符串地址
mov ecx, [eax - 4] //读取字符串长度
test esi, esi //判断是否为空指针
jz @Err
test ecx, ecx //判断字符串是否为空
jle @Err
lea eax, ValidateTbl
xor edx, edx
xor ebx, ebx
test ecx, 1
jz @LeftBytes
//FirstByte:
mov bl, [esi]
mov bl, [eax][ebx]
test ebx, 16
jnz @Err
shl bl, 4
dec edi
mov [edi], bl
dec ecx
jz @Ext
@LeftBytes:
mov bl, [esi]
mov bl, [eax][ebx]
test ebx, 16
jnz @Err
mov dl, bl
shl dl, 4
inc esi
mov bl, [esi]
mov bl, [eax][ebx]
test ebx, 16
jnz @Err
or bl, dl
dec edi
mov [edi], bl
inc esi
dec ecx
dec ecx
jnz @LeftBytes
jmp @Ext
@Err:
mov [esp], 0
@Ext:
pop eax
pop edi
pop esi
pop edx
pop ecx
pop ebx
end ;
// 测试函数,让制定的计算方法多执行几次,以拉开时间差距
function TestHexToInt(HexToIntFunc: THexToIntFunc; var Value: DWORD): DWord ;
var
I: Integer ;
begin
Result := GetTickCount ;
for I := 1 to CalcTimes do
Value := HexToIntFunc(HexStr );
Result := GetTickCount - Result ;
end ;
procedure TForm1.Button1Click(Sender: TObject );
var
Value: DWORD ;
begin
Memo1.Lines.Add(Format('HexToInt_tseug0 (%dms).', [TestHexToInt(HexToInt_tseug0, Value )]));
Memo1.Lines.Add(Format('HexToInt_tseug1 (%dms).', [TestHexToInt(HexToInt_tseug1, Value )]));
Memo1.Lines.Add(Format('HexToInt_DoubleWood (%dms).', [TestHexToInt(HexToInt_DoubleWood, Value )]));
Memo1.Lines.Add(Format('HexToInt_beta1 (%dms).', [TestHexToInt(HexToInt_beta1, Value )]));
Memo1.Lines.Add(Format('HexToInt_beta2 (%dms).', [TestHexToInt(HexToInt_beta2, Value )]));
Memo1.Lines.Add('1234' );
end ;
end.
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ,
Dialogs, StdCtrls ;
type
TForm1 = class(TForm )
Button1: TButton ;
Memo1: TMemo ;
procedure Button1Click(Sender: TObject );
private
{ Private declarations }
public
{ Public declarations }
end ;
var
Form1: TForm1 ;
implementation
{$R *.dfm}
const
HexStr: String = 'ABCD1234' ;
CalcTimes: Integer = 1000000 ;
type
THexToIntFunc = function(const S: String): DWORD ;
function HexToInt_tseug0(const S: String): DWORD ;
asm
PUSH EBX
PUSH ESI
MOV ESI, EAX //字符串地址
MOV EDX, [EAX-4] //读取字符串长度
XOR EAX, EAX //初始化返回值
XOR ECX, ECX //临时变量
TEST ESI, ESI //判断是否为空指针
JZ @@2
TEST EDX, EDX //判断字符串是否为空
JLE @@2
MOV BL, $20
@@0:
MOV CL, [ESI]
INC ESI
OR CL, BL //如果有字母则被转换为小写字母
sub CL, '0'
JB @@2 // < '0' 的字符
CMP CL, $09
JBE @@1 // '0'..'9' 的字符
sub CL, 'a'-'0'-10
CMP CL, $0A
JB @@2 // < 'a' 的字符
CMP CL, $0F
JA @@2 // > 'f' 的字符
@@1: // '0'..'9', 'A'..'F', 'a'..'f'
SHL EAX, 4
OR EAX, ECX
DEC EDX
JNZ @@0
JMP @@3
@@2:
XOR EAX, EAX // 非法16进制字符串
@@3:
POP ESI
POP EBX
RET
end ;
function HexToInt_tseug1(const S: String): DWORD ;
var
I : Integer ;
begin
Result := 0 ;
for I := 1 to Length(s) do
begin
case s[I] of
'0'..'9': Result := Result * 16 + Ord(S[I]) - Ord('0' );
'A'..'F': Result := Result * 16 + Ord(S[I]) - Ord('A') + 10 ;
'a'..'f': Result := Result * 16 + Ord(S[I]) - Ord('a') + 10 ;
else
Result := 0 ;
Exit ;
end ;
end
end ;
function HexToInt_DoubleWood(const S: string): DWORD ;
const
Convert: array[0..255] of Integer =
(
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 ,
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,- 1
);
var
I: Integer ;
v: Integer ;
begin
Result := 0 ;
if Pointer(s) = nil then exit ;
for I := 1 to PInteger(Integer(s) - 4)^ do
begin
begin
V := Convert[ord(s[i ])];
if V<0 then
begin
Result := 0 ;
Exit ;
end ;
result := (result * 16) or V ;
end ;
end ;
end ;
function HexToInt_beta1(const S: string): DWORD ;
const
ValidateTbl: array [0..255] of Byte = (
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 16, 16, 16, 16, 16, 16 ,
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 );
asm
push ebx
push ecx
push edx
push esi
push edi
mov esi, eax //字符串地址
mov ecx, [eax-4] //读取字符串长度
test esi, esi //判断是否为空指针
jz @Err
test ecx, ecx //判断字符串是否为空
jle @Err
xor eax, eax
lea edi, ValidateTbl
mov edx, ecx
xor ebx, ebx
@LoopValidate:
mov bl, [esi]
mov bl, [edi][ebx]
test ebx, 16
jnz @Err
shl eax, 4
or eax, ebx
inc esi
dec edx
jnz @LoopValidate
jmp @Ext
@Err:
xor eax, eax // 非法16进制字符串
@Ext:
pop edi
pop esi
pop edx
pop ecx
pop ebx
end ;
function HexToInt_beta2(const S: string): DWORD ;
const
ValidateTbl: array [0..255] of Byte = (
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 16, 16, 16, 16, 16, 16 ,
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 ,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 );
asm
push ebx
push ecx
push edx
push esi
push edi
mov edi, esp
push 0
mov esi, eax //字符串地址
mov ecx, [eax - 4] //读取字符串长度
test esi, esi //判断是否为空指针
jz @Err
test ecx, ecx //判断字符串是否为空
jle @Err
lea eax, ValidateTbl
xor edx, edx
xor ebx, ebx
test ecx, 1
jz @LeftBytes
//FirstByte:
mov bl, [esi]
mov bl, [eax][ebx]
test ebx, 16
jnz @Err
shl bl, 4
dec edi
mov [edi], bl
dec ecx
jz @Ext
@LeftBytes:
mov bl, [esi]
mov bl, [eax][ebx]
test ebx, 16
jnz @Err
mov dl, bl
shl dl, 4
inc esi
mov bl, [esi]
mov bl, [eax][ebx]
test ebx, 16
jnz @Err
or bl, dl
dec edi
mov [edi], bl
inc esi
dec ecx
dec ecx
jnz @LeftBytes
jmp @Ext
@Err:
mov [esp], 0
@Ext:
pop eax
pop edi
pop esi
pop edx
pop ecx
pop ebx
end ;
// 测试函数,让制定的计算方法多执行几次,以拉开时间差距
function TestHexToInt(HexToIntFunc: THexToIntFunc; var Value: DWORD): DWord ;
var
I: Integer ;
begin
Result := GetTickCount ;
for I := 1 to CalcTimes do
Value := HexToIntFunc(HexStr );
Result := GetTickCount - Result ;
end ;
procedure TForm1.Button1Click(Sender: TObject );
var
Value: DWORD ;
begin
Memo1.Lines.Add(Format('HexToInt_tseug0 (%dms).', [TestHexToInt(HexToInt_tseug0, Value )]));
Memo1.Lines.Add(Format('HexToInt_tseug1 (%dms).', [TestHexToInt(HexToInt_tseug1, Value )]));
Memo1.Lines.Add(Format('HexToInt_DoubleWood (%dms).', [TestHexToInt(HexToInt_DoubleWood, Value )]));
Memo1.Lines.Add(Format('HexToInt_beta1 (%dms).', [TestHexToInt(HexToInt_beta1, Value )]));
Memo1.Lines.Add(Format('HexToInt_beta2 (%dms).', [TestHexToInt(HexToInt_beta2, Value )]));
Memo1.Lines.Add('1234' );
end ;
end.