long long an C Funktion übergeben



  • Hi ich fange gerade erst an Assembler zu lernen und versuche gerade eine Funktion für C-Programme zu schreiben nur werden die Werte in der Funktion sehr schnell sehr groß sodass eine 4Byte Zahl nicht mehr reicht und in C gäbe es dann ja "long long" nur weis ich nicht wie ich das in Assembler realisieren soll da die Register (ich programmiere für 32bit) ja nur 32bit groß sind, ich brauche aber ja 64bit. Und Rückgabewerte werden ja in eax gespeichert oder muss ich das dann mit Pointer oder mehreren Registern machen?



  • x86 im 32Bit-Modus rechnet mit 64Bit-Zahlen idR. in eax (untere 32bit) und edx (obere 32Bit). Siehe z.B. die div und mul-Befehle. Wenn ich mich nicht irre, handhabt das C fuer Rueckgabewerte dann genauso.
    So oder so kann ein Blick in die https://de.wikipedia.org/wiki/Aufrufkonvention deines C-Compilers sicher nicht schaden.



  • bei multiplikationen sieht es aber z.B. so aus "EDX:EAX:=EAX*Op" und ich brauche ja "EDX:EAX:=EDX:EAX*Op" wie geht das denn dann?



  • pseudo code:

    /* u64[0] = low dword, u64[1] high dword */
     u64 A,B;
     u128 C = A[1]*B[1]*(2^64) + (A[0]*B[1] + A[1]*B[0])*(2^32) + A[0]*B[0];
    

    kann man Wunderbar mit MUL implementieren. Wenn es Vorzeichenbehaften sein soll, muss du A und B analysieren, eventuell das Vorzeichen wechseln und das Ergebnis entsprechend korrigieren (sofern Darstellbar).



  • kytero schrieb:

    bei multiplikationen sieht es aber z.B. so aus "EDX:EAX:=EAX*Op" und ich brauche ja "EDX:EAX:=EDX:EAX*Op" wie geht das denn dann?

    Da darf ich mal ganz unbescheiden auf meine Homepage verweisen:

    http://dcla.rkhb.de/div64.html
    Edit: Ach Du meine Güte, Du willst ja Multiplikation. Also vergiss den Link. Hier der Multiplikations-Algorithmus (EDX:EAX:=EDX:EAX*Op):

    mov ebx, edx
    	mov ecx, Op
    	mul ecx
    	push eax
    	push edx
    	mov eax, ebx
    	mul ecx
    	mov edx, eax
    	pop ebx
    	add edx, ebx
    	pop eax
    

    Mein Microsoft-VC habe ich gerade überprüft: Es übergibt "long long" auf dem Stack. Eine Funktion gibt "long long" in EDX:EAX zurück.

    viele grüße
    ralph



  • eine algemeine frage noch also wenn ich jetzt z.b. push eax mache und dann später pop bh dann werden nur die oberen 16bit vom stack genommen und in bh gespeichert richtig?



  • kytero schrieb:

    wenn ich jetzt z.b. push eax mache und dann später pop bh dann werden nur die oberen 16bit vom stack genommen und in bh gespeichert richtig?

    Wenn Du "BH" durch "BX" ersetzt: Richtig.

    Mir ist irgendwann ein Optimierungstipp über den Weg gelaufen, dass man PUSH EAX - POP EBX, also in ein anderes Register popen, nicht tun soll. Zumindest nicht zu oft.

    viele grüße
    ralph


Anmelden zum Antworten