Not logged in. · Lost password · Register

MatthiasM
Avatar
Member since Nov 2003
459 posts
Subject: Warum kann ich keine Vars auf den Stack legen???
DAS:

long Print(long v)
{
    _asm
    {
        sub    esp, 4;
        mov    esp, v; // crash (access violation)
        sub    esp, 4;
        mov    esp, v;
        add    esp, 4[esp];
        mov v, esp;
    }
   
    cout << v << "\n";

    return 1;
}

funktioniert nicht (access violation). Weiß jemand, warum?
Der Computer ist ein mechanischer Hohlkopf.
The Void
Griesgram und Zyniker
Member since Oct 2002
154 posts
Evtl. klappt's nicht, weil du den Stackpointer mit v überschreibst. Wenn du v auf den Stack kopieren willst, dann musst du ein mov [esp],v daraus machen. Ein push v würde auch ausreichen.

Bist du dir sicher, dass es schon bei der 2ten ASM-Zeile kracht? Ich würde einen Absturz erst bei add    esp, 4[esp]; vermuten.
Welcome to the worst nightmare of all --- Reality!
Antipythagoras
Siff-Lord
Avatar
Member since Feb 2003
585 posts
In reply to post #1
Steppen wir es doch mal...

_asm{
        sub    esp, 4;     //hole 4 Byte auf dem Stack. (esp -=4)
        mov    esp, v;    //schreibe v noch esp (esp = v) ist das so beabsichtigt?
        sub    esp, 4;     //ziehe von esp nochmal 4 ab. (esp = v-4)
        mov    esp, v;   //schreibe wieder v in den esp
        add    esp, 4[esp]; //schreibe den Wert aus esp (=v) nach esp+4 (das sit aber das v, das du übergeben hast +4.
        mov    v,   esp; //schreibe den esp nach v
}

Das Prog macht gar keinen Sinn. und es schreibt auch nichts auf den Stack!
Du Überschribst den esp 2MAL mit einem Völlig willkürlichen (übergebenem) Wert und wunderst dich über nen acc viol ??
semptex, c4, dünger, duschgel, deoroller, muttermilch, diet coke, mentos, Bombe, Atombombe, Uran, Anreicherung, Terror, Tote, Anschlag, Zug, Gleis, Chaos, Heil, Sturz, Anschlag, Flüssigsprengstoff, mischen, Rache, Heilig, Krieg, Gott, Feinde, Sprengstoff, Reinigungsmittel, TATP, Anleitung, Pinsellösung, Säure, Backpulver, NH4NO3, Ammoniumnitrat, Kanzleramt, Flug, Kontrolle, Waschmittel
MatthiasM
Avatar
Member since Nov 2003
459 posts
Vorsicht, da steht ein ADD in der vorletzten Zeile.
Ich will v zweimal auf den Stack legen, und dann die beiden Werte auf dem Stack addieren (v->2*v). Das Ergebnis der Addition soll wieder in v geschrieben werden. Sind vielleicht noch mehr Fehler drinnen, aber die kann ich nicht durch Trial & Error ausmerzen weil es access violation in der ZWEITEN Zeile gibt :(

Ich will nicht den Stack Pointer überschreiben, ich will den Wert von v an die Adresse schreiben, auf die esp zeigt.
Der Computer ist ein mechanischer Hohlkopf.
MatthiasM
Avatar
Member since Nov 2003
459 posts
In reply to post #2
Quote by The Void:
Evtl. klappt's nicht, weil du den Stackpointer mit v überschreibst. Wenn du v auf den Stack kopieren willst, dann musst du ein mov [esp],v daraus machen. Ein push v würde auch ausreichen.

Bist du dir sicher, dass es schon bei der 2ten ASM-Zeile kracht? Ich würde einen Absturz erst bei add    esp, 4[esp]; vermuten.

Ok ich hab 'mov [esp], v' draus gemacht, aber dann sagt der Compiler: error C2415: Ungueltiger Operandentyp

Was mir Probleme bereitet ist, dass ich nicht richtig bei der M$ Schreibweise durchblicke.

Ist () bei VC einfach []?
Also ist
mov 4(%eax), (%ebx) aus dem Skript bei M$
mov [ebx], 4[eax]
?

Es gibt wirklich eine access violation in der zweiten Zeile.
Der Computer ist ein mechanischer Hohlkopf.
The Void
Griesgram und Zyniker
Member since Oct 2002
154 posts
Ich glaube das Problem liegt darin, wie der Compiler deine Variable v im inline Assembly auflöst. Entweder löst der Compiler das v einem Zugriff über den EBP oder über den ESP auf. Ich schätze er macht es über den ESP und optimiert den EBP weg, dann kann ich mir nämlich die Access Violation schon in Zeile 2 erklären.


Ich hab mal die MOV-Anweisung nachgeschlagen und diese erwartet mindestens ein Register oder Segmentregsiter, daher funktioniert mov [esp],v nicht, da v wohl über eine memory indirect Adressierung aufgelöst wird.

Nachfolgend mal 3 Varianten, die ich jetzt nicht getestet habe, die aber funktionieren sollten.

long Print(long v)
{
    _asm
    {
        push v;
        push v;
        add [esp], [esp + 4]; //kA ob das funktioniert; Ergebnis stünde in [esp]
        pop v;
        pop eax; // braucht man nur, um den Stack wieder herzustellen
    }
  
    cout << v << "\n";

    return 1;
}

Wenn du jetzt aber unnötige Speicherzugriffe vermeiden willst und auf Codeumfang Wert legst, dann könnte deine Funktion folgendermaßen aussehen:
long Print(long v)
{
    _asm
    {
        shl v,1;
    }
    cout << v << "\n";

    return 1;
}

Wenn du jetzt aber unbedingt die MOV-Befehle verwenden willst, musst du dein v zuerst in ein freies Register schieben und dann das Register auf den Stack.
long Print(long v)
{
    _asm
    {
        mov eax,v;
        sub esp,4;
        mov [esp],eax;
        sub esp,4;
        mov [esp],eax;
        add [esp], [esp + 4];
        mov eax, [esp];
        mov v, eax;
        add esp, 8;
    }
  
    cout << v << "\n";

    return 1;
}
Welcome to the worst nightmare of all --- Reality!
MatthiasM
Avatar
Member since Nov 2003
459 posts
Hi,

Variante 1:

M$ Compiler sagt: error C2415: Ungueltiger Operandentyp für pop v;

Variante 2:

funktioniert  :gun:

Variante 3:

M$ Compiler sagt: error C2415: Ungueltiger Operandentyp für mov eax, [esp];

Das ist doch ein drecks-Compiler, da geht überhaupt nichts was Konvention ist. Trotzdem danke für die Vorschläge  :gun:
Kannst du das mit dem Optimieren noch etwas genauer erklären?
Der Computer ist ein mechanischer Hohlkopf.
MatthiasM
Avatar
Member since Nov 2003
459 posts
Was zum Teufel...

Moment!

Variante 3: Der Compiler gibt zwar an, der Fehler wäre in der Zeile mov eax, [esp];, aber wenn ich die Zeile DAVOR (add [esp], [esp + 4];) auskommentiere kompiliert's. Also mag der M$ Compiler add [esp], [esp + 4]; nicht.

Ich habe sonst noch ausprobiert:

add [esp], 4[esp];
add [esp], [esp];
add [esp + 0], [esp + 4];

ergibt alles Fehler in der darauffolgenden Zeile  :wand:
Der Computer ist ein mechanischer Hohlkopf.
MatthiasM
Avatar
Member since Nov 2003
459 posts
Ah jetzt ja!

Du hast ja gesagt:
"
Ich hab mal die MOV-Anweisung nachgeschlagen und diese erwartet mindestens ein Register oder Segmentregsiter, daher funktioniert mov [esp],v nicht, da v wohl über eine memory indirect Adressierung aufgelöst wird.
"

Darum darf man nicht zwei mal esp in einem mov benutzen. Das Nachfolgende funktioniert:

_asm
{
        mov eax,v;
        sub esp,4;
        mov [esp],eax;
        sub esp,4;
    mov [esp],eax;
    mov ebx, [esp + 4];
    add [esp], ebx;
     mov eax, [esp];
     mov v, eax;
     add esp, 8;
}

PS: WO hast du denn mov nachgeschlagen? In der VC++ 5.0 Hilfe habe ich nichts darüber gefunden.
Der Computer ist ein mechanischer Hohlkopf.
The Void
Griesgram und Zyniker
Member since Oct 2002
154 posts
PS: WO hast du denn mov nachgeschlagen? In der VC++ 5.0 Hilfe habe ich nichts darüber gefunden.

Das Buch heißt "Assembler GE-PACKT". Ansonsten einfach mal einen Blick in die Intel Prozessorhandbücher werfen, vorzugsweise ins 2te und 3te. Da stehen alle Befehle drin.
Welcome to the worst nightmare of all --- Reality!
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Go to forum
Datenschutz | Kontakt
Powered by the Unclassified NewsBoard software, 20150713-dev, © 2003-2011 by Yves Goergen