Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Delphi -> Asm -> Stackproblem? (https://www.delphipraxis.net/97098-delphi-asm-stackproblem.html)

Gruber_Hans_12345 4. Aug 2007 16:19


Delphi -> Asm -> Stackproblem?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Weiss jemand eine Möglichkeit den ASM - Code aus dem CPU Fenster als Text rauszubekommen?

Ich habe folgendes Problem, mein Delphi Code erzeugt mir einen komischen asm code, und ich weiss nicht warum, das resultat ist, das nach dem Aufruf der Funktion die Register, die eigentlich gesichert sein sollten falsch sind, wenn man sich den asm code anschaut, dann ist es klar, das die falsch sind, aber warum wird so ein code erzeugt?
Delphi-Quellcode:
procedure TRemoteNetworkInfo.RefreshAD;
var
    dom    : IADsContainer;
    i      : integer;
begin
    for i:=0 to Count-1 do Item[i].fDeleted := TRUE;

    ADsGetObject('WinNT://' + fDomainName, IADsContainer, dom);
    dom.Filter := VarArrayOf(['computer']);
    ADsEnumerateObjects(dom, AD_RefreshComputer);
    dom := nil;

    for i:=Count-1 downto 0 do
        if Item[i].fDeleted then begin
            Item[i].Free;
            Delete(i);
        end;
end;
ich habe die screenshots des CPU fensters angehängt
Speziell folgendes problem, wenn die Funktion aufgerufen wird, dann liegt die (verstekcte) variable self im EBX register
diese wird im Einstieg der Funktion auf den Stack gesichert, ABER zuvor werden in einer Schleife 9 * push $00, push $00 ausgeführt

und beim beenden der Funktion werden die Variablen (darunter auch das EBX Register) so vom Stack geladen wie wenn die 9*push $00 push $00 niemals ausgeführt worden wären

hat da jemand eine idee?




[edit]eine Lösung habe ich, um das problem zu umgehen (da ich ansonsten fehler bekommen) aber diese ist nicht wirklich soooo schön
und zwar habe ich einfach den aufruf dieser funktion gekapselt in
Delphi-Quellcode:
    asm push EBX; end;
    RefreshAD;
    asm pop EBX; end;
(wobei RefreshAD die funktion von oben ist)

sirius 4. Aug 2007 16:45

Re: Delphi -> Asm -> Stackproblem?
 
Sieht doch alles gut aus. Wo genau ist das Problem?

Der Stackpointer liegt in ebp und wird am Ende durch mov esp,ebp wieder zurückgesetzt.
Die 9 (bzw. 18) pushs dienen nur dazu um Speicherplatz für lokale Variablen (auch versteckte lokale Variablen) zu schaffen und die mit nil zu initialisieren.

Edit: dass hier: "8)" ist "acht)" :wall:
Edit2: "self" legt man sich üblicherweise in ebx (da dieses register von andeen Funktionen nicht verändert werden darf). Die Übergabe von self erfolgt trotzdem noch in eax. Wenn man allerdings aus einer Methode eine Methode derselben Klasse aufruft ist natürlich in ebx und eax dasselbe drin.

fLaSh11 4. Aug 2007 16:56

Re: Delphi -> Asm -> Stackproblem?
 
[ot]
@ sirius:
warum deaktivierst du nicht Smileys in deinem Beitrag, dann wird "8)" auch als "8)" dargestellt.
[/ot]

sirius 4. Aug 2007 17:05

Re: Delphi -> Asm -> Stackproblem?
 
Zitat:

Zitat von fLaSh11
[ot]
@ sirius:
warum deaktivierst du nicht Smileys in deinem Beitrag, dann wird "8)" auch als "8)" dargestellt.


Zitat:

Zitat von Antwort von Sirius
Weil ich daran nicht denke, wenn ich nen Beitrag abschicke :P

[/ot]


Gruber_Hans_12345 4. Aug 2007 22:26

Re: Delphi -> Asm -> Stackproblem?
 
Zitat:

Zitat von sirius
Sieht doch alles gut aus. Wo genau ist das Problem?

Der Stackpointer liegt in ebp und wird am Ende durch mov esp,ebp wieder zurückgesetzt.
Die 9 (bzw. 18) pushs dienen nur dazu um Speicherplatz für lokale Variablen (auch versteckte lokale Variablen) zu schaffen und die mit nil zu initialisieren.

Edit: dass hier: "8)" ist "acht)" :wall:
Edit2: "self" legt man sich üblicherweise in ebx (da dieses register von andeen Funktionen nicht verändert werden darf). Die Übergabe von self erfolgt trotzdem noch in eax. Wenn man allerdings aus einer Methode eine Methode derselben Klasse aufruft ist natürlich in ebx und eax dasselbe drin.

achso, moment ich glaub ich weiss was du meinst ... ich war da zu schnell und dachte, das es ein fehler sein muß, wenn der nicht in der richtigen reihenfolge popt wie er gepusht hat ... aber man sieht hier nix, da ja der stack pointer am schluß überschrieben wird, und es sein könnte, das alles richtig ist - bzw. das der asm code richtig ist, und der fehler wo anders liegt ...

also wieder erneut aufmachen und den fehler suchen ... den fakt ist, der gepushte EBX Wert (also das self) ist zum beginn der funktion richtig, aber der gepopte EBX wert ist dann falsch, deshalb funkt dann der rest aus der aufrufenden funktion dann nicht mehr

Luckie 4. Aug 2007 22:59

Re: Delphi -> Asm -> Stackproblem?
 
Zitat:

Zitat von Gruber_Hans_12345
das der asm code richtig ist, und der fehler wo anders liegt ...

Das halte ich für sehr wahrscheinlich.

Gruber_Hans_12345 4. Aug 2007 23:15

Re: Delphi -> Asm -> Stackproblem?
 
nur die frage ist, wo ist der fehler?

hjabe das ganze jetzt soweit verinfacht, das das push ebx und pop ebx noch drinnen bleibt (aber meine eigenen funktionen weg sind)

Delphi-Quellcode:
procedure TRemoteNetworkInfo.RefreshAD;
var
    dom    : IADsContainer;
    i      : integer;
begin
    //for i:=0 to Count-1 do Item[i].fDeleted := TRUE;

    ADsGetObject('WinNT://' + 'HOST', IADsContainer, dom);
    dom.Filter := VarArrayOf(['computer']);
    //ADsEnumerateObjects(dom, AD_RefreshComputer);
    //dom := nil;

    for i:=inherited Count-1 downto 0 do
        sleep(0);
        (*
        if Item[i].fDeleted then begin
            Item[i].Free;
            Delete(i);
        end;
        *)
end;
das problem ist, das zwischen dem push ebx und dem pop ebx der StackPointer um 4 Bytess verschoben ist (vor dem pop EBX müsste noch ein weiteres element gepopt werden, damit der Stack wieder richtig ist)

Gruber_Hans_12345 4. Aug 2007 23:49

Re: Delphi -> Asm -> Stackproblem?
 
so, hab das problem ...
die unit was ich verwendet habe
Delphi-Quellcode:
(************************************************************
Author: Deepak Shenoy
        [email]shenoy@agnisoft.com[/email]
Copyright (C) 2000 Agni Software Pvt. Ltd.
All Rights Reserved.
[url]http://www.agnisoft.com[/url]

Description:
Helper class for ADSI functions
********************************************************)
unit adshlp;
...
function ADsGetObject(lpszPathName:WideString; const riid:TGUID;
                      out ppObject):HRESULT; safecall; <<<< das muß stdcall sein
da müssen die funktionen in stdcall umgeändert werden (denn mit safecall legt er ein register zusätzlich am stack ab, das aber niemand abholt, und so hab ich diesen blöden fehler bekommen ... naja, war wieder mal ein kleiner ausflug in asm)

Luckie 5. Aug 2007 01:29

Re: Delphi -> Asm -> Stackproblem?
 
Na bitte, lag also doch an deinem Code und nicht am Compiler/Linker. Die Wahrscheinlichkeit, dass der Compiler/Linker kaputten ASM-Code produziert halte ich für sehr gering. Wahrscheinlicher ist da schon eher, dass der Programmiere einen Fehler macht.

sirius 5. Aug 2007 07:54

Re: Delphi -> Asm -> Stackproblem?
 
Das hat aber auch einen Grund, warum das "safecall" ist. Das solltest du nur abändern, wenn diese Funktionen/Methoden auch von deinem Speichermangaer verwaltet werden, also nicht in einer DLL ausgelagert sind. Oder das eben anderweitig sichergestellt ist, dass keine Exceptions von der DLL in dein Hauptprogramm fliegen können.

Allerdings müsste der Compiler auch bei safecall alles richtig machen. :gruebel:
Bei safecall wird das Ergebniss (HResult) als var-Parameter am Ende mit übergeben (Deswegen der zusätzliche push). In EAX (dem eigentlichen result) liegt dann ein Fehlercode vor, falls eine Exception aufgetreten ist. Normalerweise weis das der Compiler und ruft nach dem Aufruf einer safecall-Funktion immer eine Behandlungsroutine auf.

Hier, in Beitrag #9 hatte ich mal bisschen was dazu geschrieben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:10 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz