Stackpointer zurückgeben



  • Hi,
    ich habe bisher, wenn ich den Stackpointer zurückgeben lassen wollte, eine kleine Assembler-Funktion benutzt. Weis jemand ob es ein "C++"-Möglichkeit gibt, diesen zu ermitten?



  • Ok, wenn es dafür keine Möglichkeit gibt, dann eine andere Frage: Ich kopiere per Assembler den Rückgabe wert selbst nach eax. da die Funtion, die dies macht, aber unsigned long zurück geben soll, verlangt sie einen return wert. Wenn ich den aber setzte wird mein vorher nach eax kopierter wert überschrieben. Gibt es eine Möglichkeit, den Compiler zu sagen, dass man dass mit dem return-wert schon geregelt hat und er sich deshalb nicht über den fehlenden return zu beschweren braucht?



  • Wofür macht man sowas?



  • MaxDemian schrieb:

    Ok, wenn es dafür keine Möglichkeit gibt, dann eine andere Frage: Ich kopiere per Assembler den Rückgabe wert selbst nach eax. da die Funtion, die dies macht, aber unsigned long zurück geben soll, verlangt sie einen return wert. Wenn ich den aber setzte wird mein vorher nach eax kopierter wert überschrieben. Gibt es eine Möglichkeit, den Compiler zu sagen, dass man dass mit dem return-wert schon geregelt hat und er sich deshalb nicht über den fehlenden return zu beschweren braucht?

    Dazu müsste man erstmal wissen, welchen Compiler du verwendest.



  • __declspec(naked)



  • probier mal dies (für msvc6):

    unsigned long get_sp(void)
    {
       unsigned long caller_sp;
       __asm mov caller_sp, ebp;
       return caller_sp + 8;
    }
    

    ;



  • für gcc:

    inline unsigned int getStackpointer()
    {
    unsigned int stackpointer;
    __asm__ __volatile__("mov %%ebp, %%eax":"=a" (stackpointer));
    return stackpointer;
    }
    

    edit: stimmt, man muss ebp nehmen... 🕶



  • ich benutze die GCC 4.1.0



  • guckst du eins weiter oben



  • @bluecode
    wo hast du das her? gibts ja keine manpage für 😞



  • Das oben ist halt inline assembler... und das hat garnix mit Standard-C++ zu. Wenn du wissen willst wie man unter gcc inline assembler verwendet, dann ist das was für dich.
    Naja, was der Assembler-Code macht ist eigentlich ganz einfach: Der Base-Pointer (ebp, wird bei C/C++ verwendet um den stack-pointer _nach_ dem Aufruf der Funktion zu speichern) wird in das Register eax geladen. Die "output operands" sagen gcc dann noch, dass ich eax im der lokalen Variable stackpointer speichern will. Wichtig zu erwähnen ist vllt. noch, dass die Funktion auf jeden Fall vom Compiler geinlined werden muss (Zu dem Zweck könnte besser auch als Makro schreiben), da sonst die falsche Stackadresse geliefert wird. Ich hoff des is einigermaßen verständlich...

    [edit: Um mal vorzubeugen: Es bezog sich nur auf i386+ im 32-bit Protected-Mode}



  • Ich habe mir das jetzt mal durchgelesen (naja, nur teilweise verstanden^^) und hätte das jetzt eher folgendermaßen gemacht:

    __asm__ __volatile__("movl %%ebp, %0":"=r" (stackpointer));
    

    Ich habe es probiert und es funktioniert auch. Jetzt meine Frage (mal wieder^^):
    Ist es so, wie ich es oben gemacht habe nicht sicherer, weil:
    1. der compiler durch =r selbst ein register aussucht
    2. mit movl gleich gesagt wird, dass es sich um einen long handelt
    3. %0 doch die ausgabe ist (auch wenn es durchaus sinn macht, eswas in eax zu speichern und dann =a als zu lesendes register anzugeben)

    Stimmt das, was ich oben geschrieben habe? Wie gesagt, ich hab den Text nicht 100%tig verstanden :p



  • MaxDemian schrieb:

    1. der compiler durch =r selbst ein register aussucht

    jo

    MaxDemian schrieb:

    2. mit movl gleich gesagt wird, dass es sich um einen long handelt

    nö, wenn du ein 32bit register als operand nimmst, dann ist die Größe des anderen Operanden implizit gegeben. Also brauchst imho kein movl, aber ehrlich gesagt kA... 🙂

    3. %0 doch die ausgabe ist (auch wenn es durchaus sinn macht, eswas in eax zu speichern und dann =a als zu lesendes register anzugeben)

    Du musst %0 halt dann nehmen, wenn sich der Compiler ein günstiges Register aussuchen soll. Daran hab ich als ich das Codestück geschrieben hab aber auch net gedacht...


Anmelden zum Antworten