![]() |
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:
ich habe die screenshots des CPU fensters angehängt
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; 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:
(wobei RefreshAD die funktion von oben ist)
asm push EBX; end;
RefreshAD; asm pop EBX; end; |
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. |
Re: Delphi -> Asm -> Stackproblem?
[ot]
@ sirius: warum deaktivierst du nicht Smileys in deinem Beitrag, dann wird "8)" auch als "8)" dargestellt. [/ot] |
Re: Delphi -> Asm -> Stackproblem?
Zitat:
|
Re: Delphi -> Asm -> Stackproblem?
Zitat:
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 |
Re: Delphi -> Asm -> Stackproblem?
Zitat:
|
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:
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)
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; |
Re: Delphi -> Asm -> Stackproblem?
so, hab das problem ...
die unit was ich verwendet habe
Delphi-Quellcode:
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)
(************************************************************
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 |
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.
|
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. ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:43 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