Delphi XE2 assemblaggio
-
26-10-2019 - |
Domanda
Ho la seguente funzione che lavori in Delphi 2006, ma sotto Delphi XE2 dà sia un errore di violazione o di un errore di istruzione privilegiata durante l'elaborazione 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;
Non so assemblaggio molto bene. Qual è il problema?
Soluzione
Sono completamente d'accordo con il suggerimento di David semplicemente codificare questo in Pascal e hanno upvoted quella risposta. A meno che profiling ha indicato che si tratta di un vero e proprio collo di bottiglia, allora non c'è davvero alcun bisogno di ASM. Qui ci sono due versioni. Il primo è più facile da leggere, ma la seconda è più efficiente:
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;
Altri suggerimenti
Delphi 2006 utilizza caratteri byte ANSI singoli e così string
è AnsiString
, Char
è AnsiChar
. Su Delphi 2009 e in seguito, vengono utilizzati due personaggi di byte Unicode. Questa funzione non può assolutamente lavorare su entrambi i compilatori.
Anche l'hack standard utilizzando AnsiString e ANSIChar non funziona. Molto probabilmente le ipotesi che questa funzione fa circa l'attuazione RTL non è più valida in Delphi moderna sono.
vorrei riscrivere questa funzione in Pascal e lasciare che il compilatore fare il lavoro. Non solo che il modo più rapido per risolvere il tuo problema attuale, sarà anche farti superare l'ostacolo della compilazione a 64 bit dovrebbe mai decidere di affrontare questo.