Zugriffsverletzung bei call malloc



  • Hallo!
    Hätte folgendes Problem. Ich rufe innem inline-assembly

    push 24
    call malloc
    

    auf. Hier gibts aber unter Visual Studio ne Zugriffsverletzung. Kann mir jemand sagen, was ich falsch mache?

    danke! Christoph



  • Hallo,

    sicher, dass es genau an der Stelle eine Zugriffsverletzung gibt?
    Kann das sein, dass du kein "pop" machst nach dem Aufruf, ungefähr so:

    push 24
    call malloc
    pop ecx
    


  • Ja. Ich bin sicher. Ich sehe es ja beim debuggen. Deswegen habe ich mich ja gewundert. Die Zugrufssverletzung kommt unabhängig vom nachfolgenden Code.

    Christoph



  • Vermutung: Bist du sicher, dass mit der 24 auch wirklich ein dword auf den Stack gebracht wird?



  • dass mit der 24 auch wirklich ein dword auf den Stack gebracht wird

    Stimmt, vielleicht ist das gar nicht die Konstante 24, sondern eine Speicherzelle mit der Adresse 24, und die CPU versucht von dieser Adresse zu lesen und den gelesenen Wert auf den Stack zu pushen... und auf den Stack pushen ist ok, von der Adresse 24 zu lesen nicht.



  • Also da bin ich relativ sicher, dass das nicht so ist. Wenn man

    push 24
    pop eax
    

    macht, dann landet ja auch der Wert 24 in eax und nicht der Inhalt der Speichers (falls es so wäre).

    Ich bin bei

    push24
    call malloc
    pop edx
    

    von folgender Annahme ausgegangen:

    die Funktion in C lautet

    int malloc(int anzahl_bytes);
    

    .
    Es läuft doch so, dass ich der Funktion malloc mit dem Vorherigen push quasi 'anzahl_bytes' übergebe. Und wenn ich dann pop mache, müsste er mir ja den Zeiger auf den Bereich zurückgeben.

    Soweit die Überlegung. Aber irgendwass passt ihm an dem Ünergabewert nicht.

    malloc(24);
    

    klappt ja auch bestens. 😞



  • SchlitzInDaHaus schrieb:

    Also da bin ich relativ sicher, dass das nicht so ist. Wenn man

    push 24
    pop eax
    

    macht, dann landet ja auch der Wert 24 in eax und nicht der Inhalt der Speichers (falls es so wäre).

    Klar. Ich meinte auch etwas anderes, naemlich ob diese 24 als 16 oder 32Bit-Konstante auf dem Stack landet. Das laesst sich nur durch Beobachten des Stacks, bzw. stack pointers im Debugger erkennen. Wenn esp zB. nach dem push nicht mehr dword aligned (dh. glatt durch 4 teilbar) ist, hat sich da irgendwo ein 16Bit-Wert eingeschlichen, der dort nichts zu suchen hat.
    Testweise koenntest du auch mal versuchen, die 24 in irgendein 32Bit-Register (zB. eax) zu packen und das dann zu pushen.

    SchlitzInDaHaus schrieb:

    [...]Und wenn ich dann pop mache, müsste er mir ja den Zeiger auf den Bereich zurückgeben.

    Nein. Kleinere Rückgabewerte wie int, char und AFAIK auch pointer werden in eax zurueckgegeben. Was du mit pop vom Stack raeumst, ist bestenfalls der Parameter, den du vorher selbst da hingepackt hast.



  • SchlitzInDaHaus schrieb:

    Hallo!
    Hätte folgendes Problem. Ich rufe innem inline-assembly

    push 24
    call malloc
    

    auf. Hier gibts aber unter Visual Studio ne Zugriffsverletzung. Kann mir jemand sagen, was ich falsch mache?

    danke! Christoph

    Die Ursache für die Zugriffsverletzung ist die Laufzeitbibilothek ( = Multithreaded),
    wenn du die Funktion kapselst, geht's.

    // my_malloc.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
    //
    
    #include "stdafx.h"
    #include <stdlib.h>
    
    void*  my_malloc (int a)
    {
    	return malloc(a);
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        __asm	push 24
    	__asm	call my_malloc
    	__asm    add esp, 4
    
    	return 0;
    }
    

    MfG



  • Ah sehr gut! Jetzt klappst. Danke! Aber warum hast du am Ende

    add esp, 4
    

    gemacht? Das hab ich schonmal gesehen... Hab mich das da auch schon gefragt.

    Christoph



  • SchlitzInDaHaus schrieb:

    Ah sehr gut! Jetzt klappst. Danke! Aber warum hast du am Ende

    add esp, 4
    

    gemacht? Das hab ich schonmal gesehen... Hab mich das da auch schon gefragt.

    Wenn du push benutzt, um einen Wert auf den Stack zu schieben, wird esp (der Stackpointer) entsprechend verringert - in diesem Fall um 4 Byte, da der gepushte Wert so groß war. Durch add esp,4 wird der Stackpointer einfach wieder zurückgesetzt. Man könnte stattdessen auch pop aufrufen. Aber Compilercode nutzt häufig add, vermutlich da man den Stackpointer so auch nach mehreren Parametern (mehreren push's) leicht zurücksetzen kann.


Anmelden zum Antworten