![]() |
DynArray beschädigt
Hi,
Ich habe eine function, geschrieben in Assembler, die mir ein TIntArray (= Array of Integer) zurückgibt.. Will ich diese Werte jetzt ausgeben mit
Delphi-Quellcode:
dann gibt es eine AV.
A:= GiveMeAnIntArrayFunction;
Memo1.Lines.Clear; for i:= 0 to High(A) do Memo1.Lines.Add(IntToStr(A[i])); Lass ich die Werte so ausgeben ist alles in Ordnung:
Delphi-Quellcode:
:gruebel:
A:= GiveMeAnIntArrayFunction;
Caption := ''; for i:= 0 to High(A) do Caption := Caption + '|' + IntToStr(A[i]); Falls ihr jetzt dazu noch nix sagen könnt dann kann ich auch mal Teile der function oder die ganze function posten... PS: "Verbotene" Register wie EBX oder ähnliche lass ich in Ruhe... Gruß Neutral General |
Re: DynArray beschädigt
erstellst du das memo dynamisch und hast es nicht erzeugt? der unterschied zwischen den beiden ist ja eigentlich nur, wohin die sachen ausgegeben werden. GiveMeAnIntArrayFunction funktioniert ja anscheinend mindestens im 2. schnipsel.
wo genau gibt es die AV? |
Re: DynArray beschädigt
Das Memo is kein Dynamisches...Wurde zur Designzeit aufs Formular gesetzt...
Die AV entsteht bei Memo1.Lines.Add(..) Also meine function funktioniert...irgendwie.....ohne Memo...... :wall: Ach ich poste sie einfach mal...
Delphi-Quellcode:
Vorlage war diese function (Zum Vergleich und leichterem Verständnis):
function MLength(I: TIntArray): Integer;
begin Result := Length(I); end; function KaAsm(cnt: Integer): TIntArray; asm @while1: CMP eax,0 JE @end MOV edx,START MOV ecx,0 PUSH eax //cnt sichern { WHILE SCHLEIFE 2 ANFANG } @while2 : MOV eax,2 // 2 von PUSH edx CALL System.@RandInt // ..random(2) POP edx CMP eax,1 // wenn random(2) = 1 JE @Sock // springe zu sock @NSock : CMP edx,3 // größer 3? JA @minus JMP @test1 @Minus : DEC edx // ja also dec(akt) JMP @test1 @Sock : INC edx // inc(akt) @test1 : INC ecx CMP edx,ZIEL JNE @while2 { WHILE SCHLEIFE 2 ENDE} PUSH ecx MOV eax,[ebp-$04] CALL MLength INC eax PUSH eax LEA eax,[ebp-$04] MOV ecx,1 MOV edx,Result CALL System.@DynArraySetLength ADD esp,$04 MOV eax,[ebp-$04] CALL MLength POP ecx SUB eax,1 MOV edx,eax MOV eax,[ebp-$04] MOV [eax+edx*$04],ecx POP eax DEC eax JMP @while1 @end: RET end;
Delphi-Quellcode:
function KA(Cnt: Integer): TIntArray;
var akt: Integer; c: Word; begin while Cnt>0 do begin Akt:= START; C:=0; while Akt <> ZIEL do begin if Random(2)=1 then Inc(Akt) else if Akt>3 then Dec(Akt); Inc(C); end; SetLength(Result,Length(Result)+1); Inc(Result[High(Result)],c); Dec(Cnt); end; end; |
Re: DynArray beschädigt
wenn du die pascal-funktion und nicht die asm-funktion nimmst, hast du dann das gleiche AV Verhalten? wenn nicht, wird es wirklich an asm liegen.
|
Re: DynArray beschädigt
Ja es liegt an der asm function aber ich hab keine Ahnung was da schief läuft :pale:
Mit der Pascal-Version funktionierts... |
Re: DynArray beschädigt
Du hast anscheinend eine falsche Herangehensweise an Inline-Assembler (IASM).
IASM ist manchmal eine echt praktische Sache, aber man sollte es nicht übertreiben. Du musst dich ja quasi implizit mit dem Compiler von Delphi verständigen. In diesem Fall, z.B. wie der Compiler mit dyn. Arrays umgeht. Das kann man sicher alles machen, ist aber überhaupt nicht sinnvoll und führt häufig zu Problemen. Gerade Speicherbereiche reservieren und "löschen" solltest du schon dem Delphi Memory Manager überlassen. Viele Köche verderben den Brei. Wenn du alles in die Hand nehmen willst, dann solltest du kein Delphi mehr benutzen sondern z.B. MASM32, also einen "echten" Assembler. Manchmal kannst du auch gar nicht vorhersehen, was die Code-Optimierung macht. -->Fazit: Gewöhn dir bei IASM an, niemals (oder möglichst nie) Speicher zu reservieren. Falls du für dein Ergebniss aus der Assembler-Routine Speicher benötigst, dann lass ihn in der aufrufenden Routine reservieren und dann als PChar, oder PInteger, also als Pointer übergeben. Und dann kannst du in deiner Assemblerroutine mit "mov dword ptr [PInteger+4*x], irgendetwas" da reinschreiben. Soweit klar? Also am besten immer nur 32bit-Werte übergeben. roterKasten: Ich poste erstmal und les mir die beiden Beiträge gleich durch :stupid: Edit: Oh, es waren ja schon zwei Beiträge und ein veränderter. aber meiner hat noch volle gültigkeit. :mrgreen: |
Re: DynArray beschädigt
Ja das ganze sollte auch eher eine Übung sein als irgendwas sinnvolles ;)
Zitat:
|
Re: DynArray beschädigt
Etwa so:
Delphi-Quellcode:
//Das Array mit den Zahlen 1 bis 'laenge' füllen
procedure fillArray(a:Pinteger;laenge:integer); asm @@1:mov [eax+edx*4-4],edx dec edx jnz @@1 end; procedure TForm1.Button1Click(Sender: TObject); var a:array of integer; i:integer; begin setlength(a,5); fillarray(pointer(a),5); for i:=0 to 4 do memo1.lines.add(inttostr(a[i])); end; Edit: Zitat:
|
Re: DynArray beschädigt
Delphi-Quellcode:
Das komische ist: Ich hab jetzt auch das -4 hinzugefügt... und es ging im Prinzip.. Nur hatte mein Array ungefähr immer so 300 Einträge statt 10 wobei dann 290 Einträge totaler Datenmüll waren.. hab dann rumprobiert, die -4 weggemacht so das jetzt alles ist wie vorher und jetzt gehts wunderbar :gruebel:
procedure fillArray(a:Pinteger;laenge:integer);
asm @@1:mov [eax+edx*4-4],edx dec edx jnz @@1 end; |
Re: DynArray beschädigt
Versteh jetzt nicht, was du gemacht hast :gruebel:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz