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