[Delphi] ASM access violation

Pagina: 1
Acties:

  • Quitter3
  • Registratie: Januari 2001
  • Laatst online: 13-02 16:30
Ik heb een stukje asm code gevonden om een int naar een string te converteren.
Ik krijg alleen een access violation op de derde regel:

MOV ESI,[EDI]

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
procedure Q_IntToStrBuf(N: Integer; var S: string);
begin
asm
        PUSH    ESI
        PUSH    EDI
        MOV     ESI,[EDX]
        MOV     EDI ,ESI
        TEST    EAX,EAX
        JE      @@eq
        JNS     @@ns
        CMP     EAX,$80000000
        JE      @@mm
        MOV     BYTE PTR [ESI],$2D
        INC     ESI
        NEG     EAX
@@ns:   MOV     ECX,$0A
@@lp1:  XOR     EDX,EDX
        DIV     ECX
        ADD     DL,$30
        MOV     BYTE PTR [ESI],DL
        INC     ESI
        TEST    EAX,EAX
        JNE     @@lp1
        MOV     BYTE PTR [ESI],0
        LEA     ECX,[ESI-1]
        SUB     ESI,EDI
        MOV     DWORD PTR [EDI-4],ESI
        CMP     BYTE PTR [EDI],$2D
        JE      @@ws
@@lp2:  CMP     EDI,ECX
        JAE     @@qt
        MOV     AH,BYTE PTR [EDI]
        MOV     AL,BYTE PTR [ECX]
        MOV     BYTE PTR [ECX],AH
        MOV     BYTE PTR [EDI],AL
        DEC     ECX
@@ws:   INC     EDI
        JMP     @@lp2
@@qt:   POP     EDI
        POP     ESI
        RET
@@eq:   MOV     WORD PTR [ESI],$0030
        MOV     DWORD PTR [ESI-4],1
        POP     EDI
        POP     ESI
        RET
@@mm:   MOV     DWORD PTR [ESI],$3431322D
        MOV     DWORD PTR [ESI+4],$33383437
        MOV     DWORD PTR [ESI+8],$00383436
        MOV     DWORD PTR [ESI-4],11
        POP     EDI
        POP     ESI
  end;
end;


Ik roep de functie zo aan

Getal: Integer;
Str: String;
SetLength(Str, 32);
Q_IntToStrBuf(Getal, Str);

Iemand enig idee waarom het mis gaat? Ik heb al heel veel sites doorgeploegd, maar kom er nog niet uit.

  • whoami
  • Registratie: December 2000
  • Laatst online: 10:17
Waarom wil je dat met assembly doen, en wil je de gewone, standaard method in Delphi niet gebruiken?
code:
1
string s := IntToStr (5);


Trouwens, ondersteuning voor scripts / code geschreven door 3den wordt hier niet geleverd.
Als je perse dat stukje ASM wilt gebruiken, dan stel ik voor dat je contact opneemt met de maker van dat stukje code.

[ Voor 43% gewijzigd door whoami op 22-05-2003 17:08 ]

https://fgheysels.github.io/


Verwijderd

op de derde regel staat MOV ESI,[EDX]
moet die EDX niet EDI zijn? want EDX kan nu alles zijn, die heeft nog geen waarde gekregen.

edit : let maar niet op de vraag of het niet EDI moet zijn. Maar het is dus wel zo dat je een waarde van een adress probeert te lezen die je niet mag lezen.. EDX moet dus een legale waarde krijgen..

[ Voor 44% gewijzigd door Verwijderd op 22-05-2003 17:23 ]


Verwijderd

Als je geen VCL code wilt gebruiken heb ik hier een functie die hetzelfde doet...
Uiteraard alleen voor Windows.

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
function IntToStr(i: integer): string;
var
  pMessage: PChar;
begin
  if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER OR FORMAT_MESSAGE_ARGUMENT_ARRAY OR FORMAT_MESSAGE_FROM_STRING,
                PChar('%1!d!%0'),0,0,@pMessage,1,@i) <> 0) then
  try
    result := pMessage;
  finally
    LocalFree(Cardinal(pMessage));
  end;
end;