void SetCheckSum(unsigned char* temp,int Length){ unsigned long t; unsigned char x; int i,j; *(((unsigned char *)&t)+1)=*temp; *(((unsigned char *)&t)+2)=*(temp+1); for(j=2;j<Length;j++){ t=t&0x00ffff00L; *(((unsigned char *)&t)+3)=*(temp+j); for(i=0;i<8;i++){ t=t>>1; x=(unsigned char)((t&0x00000080L)>>7); if(x==1) t=t^0x00A00100L; } } *(temp+Length-2)=(unsigned char)((t&0x0000ff00)>>8); *(temp+Length-1)=(unsigned char)((t&0x00ff0000L)>>16); }
解决方案 »
- 怎样保持idhttp始终登录状态
- DBchart 的 series 怎麼動態的free掉?
- 有谁用过delphi开发过MSMQ(微软消息队列)的吗?请讲解一下如何用delphi来实现。
- 求实现多行表头的DbGrid及stringGrid控件及代码。。。 请高手帮忙
- 如何将dxdbgrid中显示的信息导出到excel里?(在线)
- 用tstringlist如何修改文本文件的某一行?
- 类似于qq的用户管理界面怎么做?
- delphi6的CORBA程序为什么只能编译不能运行?
- 请问var里面的错误
- 急急急!!!如何默认数据库文件的路径?
- 关于系统刷新问题,急!!!!!!!请帮忙看看!
- 我要使DBGrid中显示的记录以某一个字段ID升序排列,怎么设置?而且在添加一行的时候,这个字段自动加1,不用人工输入呢?
var
t: LongWord;
x: byte;
i,j: Integer;
pb1, pTemp: PByte;
begin
pTemp := temp;
pb1 := PByte(@t);
Inc(pb1);
pb1^ := pTemp^;
Inc(pb1);
Inc(pTemp);
pb1^ := pTemp^;
Inc(pb1);
pTemp := temp; for j := 2 to Length - 1 do
begin
t := t and $00ffff00;
Inc(pTemp, j);
pb1^ := pTemp^;
for i := 0 to 7 do
begin
t := t shl 1;
x := BYTE((t and $00000080) shl 7);
if x = 1 then
t := t xor $00A00100;
end;
end;
pTemp := temp;
Inc(pTemp, Length-1);
pTemp^ := BYTE((t and $0000ff00) shl 8);
Inc(pTemp);
pTemp^ := BYTE((t and $00ff0000) shl 16);
end;delphi指針操作很不方便 aaaa
asm
push ebx //寄存器 mov ebx,temp
mov ax,[ebx]
shl eax,8 mov ecx,2
@c1:
and eax,$00FFFF00
rol eax,8
mov al,[ebx+ecx]
ror eax,8
xor edx,edx
@c2:
shr eax,1
test eax,$80
jz @c3
xor eax,$00A00100
@c3:
inc edx
cmp edx,8
jl @c2
inc ecx
cmp ecx,Length
jl @c1 add ebx,length
sub ebx,2 shr eax,8
mov [ebx],ax pop ebx
end;
楼上写的不能编译呀。
错误行:pTemp^:= BYTE((t and $00ff0000) shl 16);
错误提示:Constant expression violates subrange bounds
var
t, i, j: Integer;
x: Byte;
begin
PByte(Integer(@t)+1)^ := temp^;
// *(((unsigned char *)&t)+1)=*temp;
PByte(Integer(@t)+2)^ := temp^;
// *(((unsigned char *)&t)+2)=*(temp+1);
for j:=2 to Length-1 do
begin
t := t and $00ffff00;
PByte(Integer(@t)+3)^ := PByte(Integer(temp)+j)^;
// *(((unsigned char *)&t)+3)=*(temp+j);
for i:=0 to 7 do
begin
t := t shr 1;
x := Byte((t and $00000080) shr 7);
//(unsigned char)((t&0x00000080L)>>7);
if x = 1 then
t := t xor $00A00100;
end;
end;
PByte(Integer(temp)+Length-2)^ := Byte((t and $0000ff00) shr 8);
// *(temp+Length-2)=(unsigned char)((t&0x0000ff00)>>8);
PByte(Integer(temp)+Length-1)^ := Byte((t and $00ff0000) shr 16);
// *(temp+Length-1)=(unsigned char)((t&0x00ff0000L)>>16);
end;
PByte(Integer(@t)+2)^ := PByte(Integer(temp)+1)^;
asm
push ebx mov ebx,temp
mov ax,[ebx]
shl eax,8 mov ecx,2
@c1:
and eax,$00FFFF00
rol eax,8
mov al,[ebx+ecx]
ror eax,8
xor edx,edx
@c2:
shr eax,1
test eax,$80
jz @c3
xor eax,$00A00100
@c3:
inc edx
cmp edx,8
jl @c2
inc ecx
cmp ecx,Length
jl @c1 shr eax,8
add ebx,length
dec ebx
dec ebx mov [ebx],ax
pop ebx
end;
这个应该可以了。算出来的值和那位老兄的一样了。上一次算法是对的。只是没考虑到Delphi传递参数是放在寄存器里,所以造成算出来不对,甚至于报错。
x=(unsigned char)((t&0x00000080L)>>7);
if(x==1)t=t^0x00A00100L;
翻译成: test eax,$80 是非常合理的。
实际上这一句写得有点罗嗦,而应写
if(t & 0x80) t=t^0xA00100;
换成Delphi写成:
if (t and $80)<>0 then t:= t xor $A00100;
就行了。
procedure SetCheckSum(temp: Pchar; Length: Integer);
var
t,i,j:integer;
begin
Pchar(Integer(@t)+1)^ := temp[0];
Pchar(Integer(@t)+2)^ := temp[1];
for j:=2 to Length-1 do
begin
t := t and $00ffff00;
pchar(Integer(@t)+3)^ :=temp[j];
for i:=0 to 7 do
begin
t := t shr 1;
if (t and $00000080)<>0 then t := t xor $00A00100;
end;
end;
temp[Length-2]:=char(t shr 8 and $FF );
temp[Length-1]:=char(t shr 16 and $FF);
end;
Hunto(恶魔猎手) 写的比我更精简,但是计算结果是同我一样的。
我在想,如果不正确的话,会不会这段程序本身就有问题呢?你是怎样检验的?
根据Delphi参数传递规则。第一个参数传EAX,第二个放在EDX,进行优化,使代码更少,速度更快。
procedure SetCheckSum(temp:pchar;Length:integer);
asm
push esi
mov esi,eax
add edx,esi
cld
lodsw
shl eax,8
@c1:
and eax,$00FFFF00
rol eax,8
lodsb
ror eax,8
xor ecx,ecx
@c2:
shr eax,1
test eax,$80
jz @c3
xor eax,$00A00100
@c3:
inc ecx
cmp ecx,8
jl @c2
cmp esi,edx
jl @c1
shr eax,8
mov [edx-2],ax
pop esi
end;
其实Pchar(Integer(@t)+1)^ := temp[0];完全可以写成 :Pchar(@t)[1]:=temp[0];
这样就简单多了。