先讲讲概念,Delphi的字符串(string)是一个特殊的格式,在字符串地址的前面4位,保存了字符串的长度.
这就是所谓的支持2GB
//这样你应该可以看懂
const
C_Hello = 'Hello,World';
C_Len = 4;
var
s: string;
i,j: ^integer;
begin
s := C_Hello;
i := Addr(s);
j := ptr(i^-C_Len);
showmessage(inttostr(j^));
如果要进行修改,Delphi在分配前面4个内存的时候
const
C_Hello = 'Hello,World';
C_Len = 4;
var
s: string;
i,j: ^integer;
OldProtect: Cardinal;
begin
s := C_Hello;
i := Addr(s);
j := ptr(i^-C_Len);
showmessage(inttostr(j^));
if not VirtualProtect(j, C_Len, PAGE_EXECUTE_READWRITE, OldProtect) then //把内存变为只读
SysUtils.RaiseLastWin32Error;
j^ := 8; //修改字符的长度
showmessage(inttostr(length(s))); //看看现在字符的长度是多少
showmessage(s); //在看看字符串的信息
j^ := length(C_Hello); //在修改为原来实际的长度
showmessage(s); //在看看字符
if not VirtualProtect(j, C_Len, PAGE_EXECUTE_READ, OldProtect) then
SysUtils.RaiseLastWin32Error;
// 总结,看来 showmessage,length,等都是同过读取前面4个字节的长度来处理字符串的
下面来讲讲Delphi的内部字符比较机制是
4个字符一比较
为什么要这样呢
因为现在的寄存器都是32位的,正好可以存放4个字符,1个字符占8位
如果你的字符是6位进行比较那么速度没有8个字符进行比较快.不要简单的以为循环比较,那是在高级语言中,在汇编中可没有这个概念
那么Delphi是如何进行字符比较的呢
先用要比较信息长度减输入信息长度
小于等于 //对于高级语言没有必要进行判断,对于汇编来说则需要判断
把要比较信息的长度进行保存
在把输入信息长度除以2的2次方也就是除以4
等于0 // 证明剩下要比较的信息长度小于4,
// 则进行后面1-3个字符的逐一比较,每次比较一次,
进行后面的第1个字符比较 // 1次
相等,
把剩余信息长度减1,进行判断是否为0, //对于汇编来说,就是低8位寄存器的低位 比如是AX寄存器就是Al
为0
退出
不为0
继续判断
不等
退出
进行后面的第1个字符比较 // 2次
相等,
把剩余信息长度减1,进行判断是否为0, //对于汇编来说,就是低8位寄存器的高位 比如是AX寄存器就是AH
为0
退出
不为0
继续判断
不等
退出
进行后面的第1个字符比较 // 3次
相等,
把剩余信息长度减1,进行判断是否为0, //对于汇编来说,就是高8位寄存器的低位 要比较麻烦一点把他们
// And EAX , 00FF0000 这样就可以把其它清0,正好达到了比较第3个字符的功能
为0
退出
不为0
继续判断
不等
退出
// 其实汇编的循环非常麻烦,基本用跳转和死的语句代替
不等于 // 说明剩余信息长度大于4
进行下面4位的比较.
相等
在看下面4位
把剩余长度减1,
如果为0 // 证明还有1-3位没有比较,大家知道怎么做了吧,跳转到1-3位字符串比较的地方
跳转到剩余1-3位进行比较的地方
不为0 // 证明剩下的长度大于4位
跳转到前面"进行下面4位的比较"处,进行循环处理
不相等
退出
如果大于
还原要比较信息长度,在跳转到信息比较的地方 // 输入信息长度大于信息长度,那么相减为负数,对于汇编来说当然要还原需要比较信息的长度
//对于高级语言不要这样做了,
总结,Delphi对字符进行比较就是调用上面的函数,所以可以看出,Delphi处理4的倍数个字符的速度最快
此文章由 http://www.ositren.com 收集整理 ,地址为:
http://www.ositren.com/htmls/67925.html