Assemblerroutine bringt Rechner zum absturz



  • Hi,

    ich wollte meine ersten schritte mal mit assembler testen, doch direkt ein reinfall ohne ende...

    Hier mein code:

    void CMatrix::identity (void)
    {
    #ifdef _OLD_MATH
    	this->_11 = this->_22 = this->_33 = this->_44 = 1.0f;
    	this->_12 = this->_21 = this->_31 = this->_41 = 
    	this->_13 = this->_23 = this->_32 = this->_42 = 
    	this->_14 = this->_24 = this->_34 = this->_43 = 0.0f;
    
    #else
    
    	const float a = 1.0f; 
    	const float b = 0.0f; 
    
    	_asm 
    	{ 
    		mov   eax,[matrix] 
    		mov   ebx, a 
    		mov   ecx, b 
    
    		mov   [eax],ebx 
    		mov   [eax+14h],ebx 
    		mov   [eax+28h],ebx             
    		mov   [eax+3Ch],ebx                             
    		mov   [eax+30h],ecx             
    		mov   [eax+0Ch],ecx             
    		mov   [eax+8],ecx           
    		mov   [eax+4],ecx             
    		mov   [eax+34h],ecx             
    		mov   [eax+1Ch],ecx             
    		mov   [eax+18h],ecx           
    		mov   [eax+10h],ecx           
    		mov   [eax+38h],ecx           
    		mov   [eax+2Ch],ecx           
    		mov   [eax+24h],ecx           
    		mov   [eax+20h],ecx 
    	} 
    #endif
    }
    

    wenn ich den C++ code benutze geht es, benutz ich jedoch den Assemblercode geht mir alles gnadenlos flöten...

    Die Matrixklasse sieht so aus:

    class CMatrix
    	{
    	public:
    		union 
    		{
    			struct 
    			{ 
    				float _11, _12, _13, _14; 
    				float _21, _22, _23, _24; 
    				float _31, _32, _33, _34; 
    				float _41, _42, _43, _44; 
    			};
    			float matrix[16];
    		};
    ...
    

    Was habe ich falsch gemacht? Ebenso meine Funktion für die Zeromatrix geht auch alles flöten 😞

    void CMatrix::zero (void)
    {
    #ifdef _OLD_MATH
    	this->_11 = this->_22 = this->_33 = this->_44 = 
    	this->_12 = this->_21 = this->_31 = this->_41 = 
    	this->_13 = this->_23 = this->_32 = this->_42 = 
    	this->_14 = this->_24 = this->_34 = this->_43 = 0.0f;
    
    #else
    
    	const float a = 0.0f; 
    
    	__asm 
    	{ 
    		mov   eax,[matrix] 
    		mov   ebx, a 
    
    		mov   [eax],ebx 
    		mov   [eax+14h],ebx 
    		mov   [eax+28h],ebx             
    		mov   [eax+3Ch],ebx                             
    		mov   [eax+30h],ebx             
    		mov   [eax+0Ch],ebx             
    		mov   [eax+8],ebx           
    		mov   [eax+4],ebx             
    		mov   [eax+34h],ebx             
    		mov   [eax+1Ch],ebx             
    		mov   [eax+18h],ebx           
    		mov   [eax+10h],ebx           
    		mov   [eax+38h],ebx           
    		mov   [eax+2Ch],ebx           
    		mov   [eax+24h],ebx           
    		mov   [eax+20h],ebx 
    	} 
    #endif
    }
    


  • 1. Es ist käse ASM zu benutzen um da nur mov zu benutzen um die Matrix zu füllen.
    Damit erzielst du kaum Geschwindigkeitsvorteile.

    2. Bin ich mir nicht sicher ob du einen float-Wert einfach so in das ebx Register laden kannst. Es ist zwar auch 32 Bit breit, hat aber ein spezielles format. Gleitpunktvariablen werden normal von den FPU-Registern verarbeitet.



  • Kann man schon, wenn sich der Compiler nicht drüber beschwert.

    Du willst in der ersten Zeile aber nicht den Inhalt von matrix laden, sondern die Adresse -> eckige Klammern weg.



  • Hi,

    @Ringding
    wenn ich es so schreibe:

    mov   eax, matrix
    		mov   ebx, a 
    		mov   ecx, b
    

    schmiert er ab 😞

    Wie würdet ihr das machen? Ich weis das das käse ist, aber wenn du richtig gelesen hättest, wüsstest du das ich grade nur erste gehversuche mache in Assembler.



  • mach deine ersten assemblerversuche lieber mit einem assembler und nicht mit inline asm in c++. du kannst nie genau wissen was dein c++ compiler gerade macht und wie das mit deinem inline code in konflikt steht. es sei denn du benutzt nen debugger, aber auch dafür sollte man sich mit asm gut auskennen. alleine schon diese zeile void CMatrix::identity (void) kann mindestens 3 zeilen asm code bedeuten, die mit deinem code irgendwie in konflikt treten können, z.b wenn dieselben register benutzt werden usw.
    deshalb schnapp dir lieber ein asm buch für einsteiger und fang klein an.

    btw, in deinem code kann es daran liegen dass du auf eine speicherstelle zugreifst, die nicht zur matrix gehört, also würde ich diese abschnitte nochmal überprüfen:
    mov [eax],ebx
    mov [eax+14h],ebx
    mov [eax+28h],ebx
    mov [eax+3Ch],ebx
    mov [eax+30h],ecx
    mov [eax+0Ch],ecx
    mov [eax+8],ecx
    mov [eax+4],ecx
    mov [eax+34h],ecx
    mov [eax+1Ch],ecx
    mov [eax+18h],ecx
    mov [eax+10h],ecx
    mov [eax+38h],ecx
    mov [eax+2Ch],ecx
    mov [eax+24h],ecx
    mov [eax+20h],ecx



  • Hi,

    die speicherbereiche sind richtig. Ich habe was interessantes rausgefunden:

    Wenn ich das hier mache mit CMatrix c = this; funzt es einwandfrei!

    void CMatrix::identity (void)
    {
    #ifdef _OLD_MATH
    
    	this->_11 = this->_22 = this->_33 = this->_44 = 1.0f;
    	this->_12 = this->_21 = this->_31 = this->_41 = 
    	this->_13 = this->_23 = this->_32 = this->_42 = 
    	this->_14 = this->_24 = this->_34 = this->_43 = 0.0f;
    
    #else
    
    	const float a = 1.0f; 
    	const float b = 0.0f; 
    	CMatrix *c = this;
    
    	__asm 
    	{ 
    		mov   eax, c
    		mov   ebx, a 
    		mov   ecx, b 
    
    		mov   [eax],ebx 
    		mov   [eax+14h],ebx 
    		mov   [eax+28h],ebx             
    		mov   [eax+3Ch],ebx  
    
    		mov   [eax+30h],ecx             
    		mov   [eax+0Ch],ecx             
    		mov   [eax+8],ecx           
    		mov   [eax+4],ecx             
    		mov   [eax+34h],ecx             
    		mov   [eax+1Ch],ecx             
    		mov   [eax+18h],ecx           
    		mov   [eax+10h],ecx           
    		mov   [eax+38h],ecx           
    		mov   [eax+2Ch],ecx           
    		mov   [eax+24h],ecx           
    		mov   [eax+20h],ecx 
    	} 
    
    	*this = *c;
    #endif
    }
    

    Warum ist das so, und wie kann ichs machen, dass ich nicht this benutzen muss sondern direkt auf das Floatarray 'matrix' zugreifen kann? 😕



  • *push* plz help 😞



  • In ecx liegt glaub ich der this pointer in Visual C++. Deshalb bloß nicht überschreiben.



  • liegt daran weil ich darin den this pointer rein gestopft habe? aber frage wie ich direkt auf das array zugreifen kann?



  • Vielleicht auch &matrix verwenden. Aber es stimmt schon, inline Assembler ist immer ein bisschen mühsam, weil man nie so ganz sicher sein kann, was der Compiler genau damit macht.



  • hatte ich auch schon ausprobiert:

    mov   eax, &matrix
    

    diese zeile macht das hier:
    error C2400: inline assembler syntax error in 'second operand'; found 'AND'



  • wenn dann:
    mov eax,offset matrix
    oder etwa nicht?



  • bringt das hier:
    error C2415: improper operand type



  • @Nobuo T
    kannst du nicht helfen? 😞



  • Hi.

    Versuchs mal mit

    lea eax, [matrix]
    

    (habe gerade kein VC++ installiert, also keine Ahnung ob das funktioniert)



  • Hi,

    da bekomm ich diesen Fehler:
    error C2415: improper operand type

    das ist so gemein 😞



  • kann mir den keiner helfen? 😞



  • Schonmal geguckt, was der Compiler aus deinem alten Code macht?
    Ist vielleicht noch ein Ansatzpunkt.
    Solange du mir hier keinen Rechner mit VC++ herzaubern kannst, bleibt dir wohl nur selber probieren und weiter warten. 🙄



  • Nobuo T schrieb:

    Schonmal geguckt, was der Compiler aus deinem alten Code macht?
    Ist vielleicht noch ein Ansatzpunkt.
    Solange du mir hier keinen Rechner mit VC++ herzaubern kannst, bleibt dir wohl nur selber probieren und weiter warten. 🙄

    Hast du nun VC++? Bisher konnte ich nichts dran rausfinden 😞



  • Ja, hast Glueck, dass mir in den Ferien so langweilig geworden ist, dass ich das Monstrum mal wieder ausgepackt habe. 😃
    Folgendes liess sich compilieren und ist zumindest nicht abgestuerzt:

    void CMatrix::identity (void) 
    { 
        const float a = 1.0f; 
        const float b = 0.0f; 
    
        _asm 
        { 
            lea   eax, this
            mov   ebx, a 
            mov   ecx, b //...
    

Anmelden zum Antworten