Delphi XE2 ensemble
-
26-10-2019 - |
Question
J'ai la fonction suivante que les travaux de Delphi 2006, mais sous Delphi XE2 il donne soit une erreur de violation d'accès ou d'une erreur d'instruction privilégiée lors du traitement 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;
Je ne sais pas très bien l'assemblage. Quel est le problème?
La solution
Je suis entièrement d'accord avec la suggestion de David à coder simplement ceci en Pascal et ont upvoted cette réponse. À moins de profilage a indiqué que c'est un véritable goulot d'étranglement alors il n'y a vraiment pas besoin de l'ASM. Voici les deux versions. La première est plus facile à lire, mais le second est plus efficace:
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;
Autres conseils
Delphi 2006 utilise des caractères ANSI seul octet et ainsi string
est AnsiString
, Char
est AnsiChar
. Delphi 2009 et plus tard, deux caractères Unicode octet sont utilisés. Cette fonction ne peut pas peut-être travailler sur les deux compilateurs.
Même le hack standard d'utilisation AnsiString et AnsiChar ne fonctionne pas. Très probablement les hypothèses que cette fonction fait au sujet de la mise en œuvre de RTL ne sont plus valides dans Delphi moderne.
Je récrire cette fonction Pascal et laisser le compilateur faire le travail. Non seulement que ce sera le meilleur moyen de résoudre votre problème actuel, il sera également vous aider à franchir l'obstacle de la compilation 64 bits si vous choisissez toujours d'aborder ce sujet.