Ohne temporäre variablen



  • Hallo

    Kann ich das Gleiche ohne die Variablen s und c erreichen? Wenn der Rückgabewert ein int wäre, dann könnte ich den Wert ja in eax verschieben. Wie geht das bei einem double? Und kann ich vom __asm Block aus direkt den Parameter cos überschreiben?

    double Sincos(double x, double& cos)
    {
    	double s, c;
    
    	__asm
    	{
    		fld x
    		fsincos
    		fstp c
    		fstp s
    	}
    
    	cos = c;
    	return s;
    }
    


  • Man könnte auf die lokale Variable s ganz verzichten und diese nicht "poppen", sondern ruhig in st(0) stehen lassen. Ich würde dafür meine Hand nicht ins Feuer legen.
    Wie es mit Handhabung von Referenzen in asm Code ist, weiß ich leider nicht. Was ist eine Referenz eigentlich auf asm Ebene betrachtet, eine Adresse? Wenns eine Adresse ist, dann wäre es einfach schön - diese ruhig in ein Register laden und darauf "poppen"...



  • abc.w schrieb:

    Man könnte auf die lokale Variable s ganz verzichten und diese nicht "poppen", sondern ruhig in st(0) stehen lassen. Ich würde dafür meine Hand nicht ins Feuer legen.

    Ich auch nicht. Irgendwas muss er im C-Code schliesslich zurueckgeben. Alternative waere, die ganze Funktion in Assembler zu schreiben.

    abc.w schrieb:

    Wie es mit Handhabung von Referenzen in asm Code ist, weiß ich leider nicht. Was ist eine Referenz eigentlich auf asm Ebene betrachtet, eine Adresse? Wenns eine Adresse ist, dann wäre es einfach schön - diese ruhig in ein Register laden und darauf "poppen"...

    Ja, ist eine Adresse. Das sollte auch in inline-asm ohne Probleme gehen.



  • double Sincos(double x, double* cos) 
    { 
        __asm 
        { 
            fld  x 
            fsincos 
            mov  eax, cos
    		fstp qword ptr [eax]
            fstp x 
    		fld  x
    	} 
     }
    

    Hab das mal kurz im Visual-Studio geschrieben.
    Nur der Funktionsrahmen in Hochsprache , den Rückgabewert holt sich der
    Compiler aus dem TOS ( fstp qword ptr [retun_zuweisung]; )

    mfg



  • sorry, Funktion ist nur 4 asm-befehle lang.

    double Sincos(double x, double* cos) 
    { 
        __asm 
        { 
            fld  x 
            fsincos 
            mov  eax, cos
    		fstp qword ptr [eax]
    	} 
    }
    

    Der double-Rückgabewert liegt wie gesagt im TOS bereit.

    Die Funktion musste ich mit einem Zeiger schreiben.
    Würde eine Referenz übergeben, komme ich mit Assembler nicht an die Orginalvariable ran.
    Mir fehlen die Adressverbindungs-Informationen die bei einer Referenz dem Compiler bekannt sind.
    Ich könnte die Referenz nur als lokale Variable im Funktonskopf ansprechen.
    Deswegen musste ich die Fuktion mit einem double* statt einer Referenz schreiben.

    mfg



  • Ok, vielen Dank! Das scheint zu funktionieren. Komisch ist allerdings, dass mein Compiler (VC++ 2005) bei der Releasekonfiguration (/Ox) in einen Endlosloop kommt. Kann das jemand bestätigen?

    double Sincos(double x, double* cos)
    {
        __asm
        {
            fld  x
            fsincos
            mov  eax, cos
            fstp qword ptr [eax]
        }
    }
    
    int main(int argc, char** argv)
    {
    
    	double s, c;
    
    	s = Sincos(1.5, &c);
    
    	std::cout << s << '\t' << c << '\n';
    
    	return 0;
    }
    


  • Stefan schrieb:

    Ok, vielen Dank! Das scheint zu funktionieren. Komisch ist allerdings, dass mein Compiler (VC++ 2005) bei der Releasekonfiguration (/Ox) in einen Endlosloop kommt. Kann das jemand bestätigen?

    Stimmt, der Compiler kommt beim Release-Build in eine Endlosschleife, also muss der
    Returnwert für den Compiler mit return übergeben werden, so wie es die Hochsprache verlangt.

    double Sincos(double x, double* cos)
    {
        __asm
        {
            fld  x
            fsincos
            mov  eax, cos
            fstp qword ptr [eax]
    		fstp x
        }
    	return x;
    }
    

    mfg


Anmelden zum Antworten