malloc vom inline assembler aus aufrufen



  • Hallo zusammen,

    was bitte schön ist so schwierig daran malloc per inline assembler (VC 9.0) aufzurufen? Folgender Code bringt bei mir jedes mal eine Access Violation mitsich:

    char* lpszTest = NULL;
    
    	__asm {
    [asm]		push	32
    		call	malloc
    		test	eax, 0
    		jz		_end
    		lea		edx, lpszTest
    		mov		[edx], eax
    
    _end:[/asm]
    	}
    
    	if( lpszTest != NULL )
    		free(lpszTest);
    

    Diese tritt immer direkt beim Aufruf (call) von malloc auf. Da die Funktion als __cdecl deklariert ist, gehe ich von einer Parameterübergabe vom Stack aus. Da nur ein Parameter vorhanden spielt die Reihenfolge ja keine Rolle ...



  • Sicher, dass es direkt beim call ist? Was mir auffällt, ist, dass du den Parameter nicht wieder vom Stack nimmst, also ein add esp, 4 nach dem call fehlt.



  • taljeth schrieb:

    Sicher, dass es direkt beim call ist? Was mir auffällt, ist, dass du den Parameter nicht wieder vom Stack nimmst, also ein add esp, 4 nach dem call fehlt.

    Ja, da hast du recht. Ist aber auch nicht nötig, da der Fehler halt DIREKT beim Aufruf geschieht - laut Debugger jedenfalls.

    Trotzdem danke.

    Ich hätte da mal noch eine andere Frage, für die es sich nicht lohnt einen neuen Thread zu eröffnen:

    Ich habe folgende Funktion:

    function CmpStr(const S1, S2 : IsamKeyStr): Integer; assembler;
      asm
      	{ EAX -> S1
          EDX -> S2 }
    
        push	edi
        push	esi
    
        cld
        mov		edi, edx
        mov		esi, eax
    
        xor		eax, eax					// null result
    
        xor		ecx, ecx
        mov		cl, byte ptr[edi]
        mov		dl, byte ptr[esi]
    
        cmp		cl, dl
        jne		@@LenNotEqual			// different
    
        shr		ecx, 1						// compare dwords
        jz  	@@Rest
    
        repe  cmpsw   					// 0 = Strings are equal  !0 = not equal
        jnz		@@StrNotEqual
    
      @@Rest:
      	mov		cl, dl
        and		ecx, 3						// get remaining bits
    
        repe	cmpsb 						// 0 = Strings are equel  !0 = not equl
      	jz		@@Exit						// Strings are equal
    
      @@StrNotEqual:
      	dec		eax
        jmp		@@Exit
    
      @@FirstShorter:
      	inc		eax
        jmp		@@Exit
    
      @@LenNotEqual:
      	ja		@@FirstShorter  	// s1 < s2
        dec		eax               // s1 > s2
    
      @@Exit:
        pop		esi
        pop		edi
      end;
    

    Funktioniert einwandfrei. Nur, sollten beide Strings gleich lang sein UND sich im LETZTEN Zeichen unterscheiden UND der zu vergleichende rest 1 (Bit) sein, dann ergibt der Vergleich 0 ... darf aber nicht sein.



  • push 20h
    call dword ptr [malloc]
    add esp, 04h
    

    Done.



  • /rant/ schrieb:

    push 20h
    call dword ptr [malloc]
    add esp, 04h
    

    Done.

    Wie weiss eigentlich der Assembler bei dem push 20h Befehl, ob es ein 16 oder 32 Bit Operand ist? malloc erwartet ja ein size_t Operand und size_t ist 32 Bit.
    😕



  • AFAIK benutzt ein push mit 32 Bit Immediate das Register ESP für den Stack-Zugriff wohingegen ein push mit 16 Bit Immediate nur SP benutzt (alte 16 Bit Variante des Befehls), was natürlich zum Problem werden kann. Zusammen mit der Tatsache, dass man den Stack schön an 4 Byte Grenzen ausgerichtet haben will (Stichwort Alignment) ist es für den Assembler nahe liegend, 32 Bit Immediates als Standard zu verwenden.

    MfG


Anmelden zum Antworten