Quersumme per Schleife



  • @Elias, hier ist noch eine andere Lösung. Diese basiert jedoch nicht auf einem String sondern auf einem normalen int-Wert. Das ganze ist dann natürlich auf sizeof( int ) 🙂 begrenzt.

    div_t iRes;
    int iNum = 123456789;
    int iSum = 0;
    
    while ( iNum )
    {
      iRes = div( iNum, 10 );
      iNum = iRes.quot;
      iSum += iRes.rem;
    };
    


  • Würds auch mit cin oder so entgegennehmen und dann entweder
    1)

    long QuerSumme (char*String)
    {
      long len=0,temp=0;
      char*pString=String;
      if(String==NULL)
        return -1;
      if((len=strlen(String))<=0)
        return -1;
      for(long i=0;i<len;i++,pString++)
      {
        if((*pString)>=48 && ((*pString)<=57))
          temp+=(*pString)-48;
        else
          return -1;
      }
      return temp;
    }
    

    [Natürlich noch mit überlaufscheck!]

    oder
    2)

    __declspec(naked)  long __stdcall Funct (char*String)
    {
    	__asm
    	{
    		push ebp;
    		mov ebp,esp;
    		mov edx,dword ptr [ebp+0x8];
    		xor ecx,ecx;
    		xor eax,eax;
    		cmp edx,0;
    		je L_Funct_End;
    		dec edx;
    L_Funct_Loop:
    		inc edx;
    		mov al,byte ptr[edx];
    		cmp eax,47;
    		jge L_Funct_Bigger;
    		cmp eax,0;
    		jne L_Funct_Loop;
    		mov eax,ecx;
    		mov esp,ebp;
    		pop ebp;
    		ret 0x4;
    
    L_Funct_Bigger:
    		cmp eax,58;
    		jge L_Funct_End;
    		sub eax,48;
    		add ecx,eax;
    		jmp L_Funct_Loop;
    
    L_Funct_End:
    		xor eax,eax;
    		mov esp,ebp;
    		pop ebp;
    		ret 0x4;
    	}
    }
    

    Natürlich fehlt auch da der überlaufsschutz!
    Wenns auf geschwindigkeit ankommt ist 2 besser! Aber es ist noch nicht das optimum 😉 !!!!!
    Besser kann ichs halt ned...
    Viel Spaß noch
    MFG Manuelh87


  • Mod

    __declspec( naked ) int __fastcall Quersumme(char const* String)
    {
        __asm
        {
            xor     eax, eax
            xor     edx, edx
    loop:   add     eax, edx
            movzx   edx, byte ptr [ ecx ]
            inc     ecx
            sub     edx, '0'
            cmp     edx, 10
            jc      loop
            ret
        }
    }
    

    geht so nat. nicht mit dem borland compiler (und mit gcc ebensowenig), weil der eine andere fastcall konvention benutzt.



  • Naja! Dein code läuft wahrscheinlich noch 10x schneller als meiner 👍!
    Wielange machts du das schon camper?

    Nur ne frage: überprüfst du auch auf das NULL beim String! Ich kenn leider das movzx (oder was du da verwendest) und das jc nicht! Bin auf dem Sektor leider noch ziemlicher anfänger 😃 !

    Noch so am Rande: Ich hab n bissal einen komischen Stil oder? Aber ich fang eben erst an und wollt mal ne Funktion in inline asm probiern. Es hat mich aber schon ziemlich gefreut das meine Funktion zumindest schneller als die in C++ war :D) Aber ich glaub da hab ich noch ne menge zu lernen damit mein code auch mal zu kurz und bündig wie deiner wird :D! Naja jetzt geh ichs jedenfalls an!!!

    PS: Nochmal danke für den code! 😉

    MFG Manuelh87



  • Hey Ich glaub ich habs checkt!

    movzx   edx, byte ptr [ ecx ]
    

    movzx fügt in ein dword ein byte rein!
    bei mov müsst ich dl,byte ptr [ecx] schreiben, richtig?

    jc müsste dann sowas bewirken wie jump wenn größer oder gleich 0 und kleiner als 10, stimmt das so??
    Ich mag dich aber ned mit blöden fragen bombadieren; wärds ma mal gescheit durchlesen !
    wollt nur meinen einwand zurücknehmen.... 😃
    cu Manuelh87


  • Mod

    jc (jump if carry) ist nur eine andere schreibweise für jb (jump if below), also wenn z.b. eine vorherige vorzeichenlose operation einen übertrag (carry) bewirkt hat. diesbezgl. fragen sind allerdings im assembler forum besser aufgehoben. im übrigen war die funktion hier auf ein minimum reduziert. parameter überprüfung und formatierungsfehler hab ich ausgelassen. (NULL zu übergeben ist sowieso ein logikfehler). das könnte man z.b. so haben:

    __declspec( naked ) int __fastcall Quersumme(char const* String)
    {
        __asm
        {
    #ifdef _DEBUG
            or      ecx, ecx       // String == NULL ?
            jnz     passed          // könnte man auch als ASM_ASSERT macro schreiben
            int     3              // Breakpoint
    passed:
    #endif
            xor     eax, eax
            xor     edx, edx
    loop:   add     eax, edx
            movzx   edx, byte ptr [ ecx ]
            inc     ecx
            sub     edx, '0'
            cmp     edx, 10
            jc      loop
            cmp     edx, -'0'
            jnz     error
            ret
    error:
            mov     eax, -1
            ret
        }
    }
    

    andererseits ist die ganze funktion sowieso overkill und völlig nutzlos 😉



  • Seit wann ist dieses Forum zu einer asm-Spielwiese verkommen in dem alle zeigen können was sie denn für toll komplizierten Code schreiben können? Einfache Frage, einfache Antwort (und sei sie "google"), aber hier die Anfänger zu verwirren finde ich nicht sehr nett.



  • Sorry ich will echt nimanden verwirren. We camper schon gesagt hat gehört das eh besser ins asm forum. 👍 Aber niemand will da mit können angeben camper wollt mir nur zeigen wie es besser gemacht gehört was meines erachtens sehr wichtig ist!! 👍

    Und ich hab eben erst angefangen und da hab ichs halt mal so probiert.... aber es ist auch ne c++ rein variante da! (Geh eh schon ins asm Forum mit sowas... 😃 👍 )

    cu Manuelh87



  • Manuelh87 schrieb:

    Aber niemand will da mit können angeben camper wollt mir nur zeigen wie es besser gemacht gehört was meines erachtens sehr wichtig ist!! 👍

    Am "besten" macht man so was garnicht in asm. Ist nur unlesbar und der Performancegewinn ist minimal oder nicht existent. 😉



  • MaSTaH schrieb:

    Am "besten" macht man so was garnicht in asm. Ist nur unlesbar und der Performancegewinn ist minimal oder nicht existent. 😉

    also bei meiner variante war er schon bis zu 4x und bei seiner ist er sicher nochhöher... und wenn man asm checkt dann ist das verstehen auch ned soviel schwerer wie bei c++.
    Es kommt natürlich auf das einsatzgebiet an... und da geb ich da recht dass das wahrscheinlich übertrieben ist es in asm zu schreiben! 😃
    Aber irgendwann und iregendwo muss ma ja anfangen.. ich ich bin über jeden froh der mir da konstruktive tips gibt wie camper (zum Beispiel).. 👍

    MFG Manuelh87



  • camper ist das beste Forenmitglied hier. 👍 👍 👍 👍 👍



  • Manuelh87 schrieb:

    MaSTaH schrieb:

    Am "besten" macht man so was garnicht in asm. Ist nur unlesbar und der Performancegewinn ist minimal oder nicht existent. 😉

    also bei meiner variante war er schon bis zu 4x und bei seiner ist er sicher nochhöher... und wenn man asm checkt dann ist das verstehen auch ned soviel schwerer wie bei c++.

    Glaub ich nicht! Wer behauptet, dass eine handgeschriebene Asm-Version einer Quersummenfunktion schneller ist als das, was ein ompiler aus dem C++ Code macht der hat das nicht oder falsch nachgemessen. Ausserdem geht es hier nicht darum, dass niemand den Code "checkt", sondern darum, dass dies ein C++ Forum und noch dazu eine Einsteigerfrage ist, also ein denkbar ungeeigneter Platz für Asm-Experimente.


Anmelden zum Antworten