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?

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top