我有以下在Delphi2006中工作的函数,但在Delphi XE2下,当处理RET时,它会给出访问冲突错误或特权指令错误。
function Q_TrimChar(const S: string; Ch: Char): string;
asm
PUSH ESI
MOV ESI,ECX
TEST EAX,EAX
JE @@qt
MOV ECX,[EAX-4]
TEST ECX,ECX
JE @@qt
PUSH EBX
PUSH EDI
MOV EBX,EAX
MOV EDI,EDX
XOR EDX,EDX
MOV EAX,ESI
CALL System.@LStrFromPCharLen
MOV EDX,EDI
MOV ECX,[EBX-4]
@@lp1: CMP DL,BYTE PTR [EBX]
JNE @@ex1
INC EBX
DEC ECX
JNE @@lp1
MOV EDX,[ESI]
JMP @@wq
@@ex1: DEC ECX
@@lp2: CMP DL,BYTE PTR [EBX+ECX]
JNE @@ex2
DEC ECX
JMP @@lp2
@@ex2: MOV EDI,[ESI]
LEA EDX,[EDI+ECX+1]
@@lp3: MOV AL,BYTE PTR [EBX+ECX]
MOV BYTE PTR [EDI+ECX],AL
DEC ECX
JNS @@lp3
@@wq: MOV EAX,[ESI]
MOV BYTE PTR [EDX],0
SUB EDX,EAX
MOV [EAX-4],EDX
POP EDI
POP EBX
POP ESI
RET
@@qt: MOV EAX,ESI
CALL System.@LStrClr
POP ESI
end;我对汇编不是很了解。有什么问题吗?
发布于 2012-02-17 10:13:16
我完全同意David的建议,简单地用Pascal编写代码,并支持这个答案。除非分析表明这是一个真正的瓶颈,否则就没有必要使用ASM。这里有两个版本。第一个更容易阅读,但第二个更高效:
function Q_TrimChar(const S: string; Ch: Char): string;
begin
result := S;
while (result <> '') and (result[1] = Ch) do Delete(Result, 1, 1);
while (result <> '') and (result[Length(Result)] = Ch) do Delete(Result, Length(Result), 1);
end;
function Q_TrimChar(const S: string; Ch: Char): string;
var
First, Last : integer;
begin
First := 1;
Last := Length(S);
while (First < Last) and (S[First] = Ch) do inc(First);
while (Last >= First) and (S[Last] = Ch) do Dec(Last);
Result := copy(S, First, Last-First+1);
end;发布于 2012-02-17 08:45:58
Delphi2006使用单字节ANSI字符,因此string是AnsiString,Char是AnsiChar。在Delphi 2009和更高版本中,使用两个字节的Unicode字符。这个函数不可能同时在两个编译器上工作。
即使是使用AnsiString和AnsiChar的标准技巧也不起作用。这个函数对RTL实现的假设很可能在现代Delphi中不再有效。
我会用Pascal重写这个函数,让编译器来完成这项工作。这不仅是解决您当前问题的最快方法,而且如果您选择解决这个问题,它还将帮助您克服64位编译的障碍。
https://stackoverflow.com/questions/9321350
复制相似问题