德尔福XE2总成
我有以下函数可以在 Delphi 2006 中运行,但在 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;
我不太了解汇编。问题是什么?
I have the following function that works in Delphi 2006, but under Delphi XE2 it gives either an access violation error or a privileged instruction error when processing 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;
I don't know assembly very well. What is the problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我完全同意 David 的建议,即简单地用 Pascal 进行编码,并已对该答案投了赞成票。除非分析表明这是真正的瓶颈,否则实际上不需要 ASM。这里有两个版本。第一个更容易阅读,但第二个更有效:
I completely agree with David's suggestion to simply code this in Pascal and have upvoted that answer. Unless profiling has indicated that this is a true bottleneck then there's really no need for the ASM. Here are two versions. The first is easier to read but the second is more efficient:
Delphi 2006 使用单字节 ANSI 字符,因此
string
为AnsiString
,Char
为AnsiChar
。在 Delphi 2009 及更高版本上,使用两字节 Unicode 字符。该函数不可能在两个编译器上都工作。即使使用 AnsiString 和 AnsiChar 的标准 hack 也不起作用。最有可能的是,该函数对 RTL 实现所做的假设在现代 Delphi 中不再有效。
我会用 Pascal 重写这个函数并让编译器完成工作。这不仅是解决您当前问题的最快方法,而且如果您选择解决该问题,它还可以帮助您克服 64 位编译的障碍。
Delphi 2006 uses single byte ANSI characters and so
string
isAnsiString
,Char
isAnsiChar
. On Delphi 2009 and later, two byte Unicode characters are used. This function cannot possibly work on both compilers.Even the standard hack of using AnsiString and AnsiChar does not work. Most likely the assumptions that this function makes about the RTL implementation are no longer valid in modern Delphi.
I would re-write this function in Pascal and let the compiler do the work. Not only will that be the quickest way to solve your current problem, it will also get you over the hurdle of 64-bit compilation should you ever choose to tackle that.