Schöne Aufgabe



  • floorball schrieb:

    Also nachdem ich mir die Aufgabe nochmal durchgelesen habe, habe ich jetzt gemerkt, dass es mit ror bzw. rol nicht funktionieren kann, da man das Byte ja nicht rotieren sondern (wenn ich es jetzt richtig verstanden habe) in der Mitte spiegeln soll.

    Aber mit rcr und rcl sollte es einfacher klappen.



  • blurry333 schrieb:

    Lol sobald man ein array hat gehts schon leichter. Aber probiers mal ohne. sondern mit >> Operator . Ich hab noch keine Lösung. Also mit bitset ist es schon leicht klar.

    Lookup table ...



  • knivil schrieb:

    blurry333 schrieb:

    Lol sobald man ein array hat gehts schon leichter. Aber probiers mal ohne. sondern mit >> Operator . Ich hab noch keine Lösung. Also mit bitset ist es schon leicht klar.

    Lookup table ...

    Die man mit einem C-Programm generiert 😃



  • blurry333 schrieb:

    Lol sobald man ein array hat gehts schon leichter. Aber probiers mal ohne. sondern mit >> Operator . Ich hab noch keine Lösung. Also mit bitset ist es schon leicht klar.

    #include <stdio.h>
    
    void println_bin (unsigned char a)
    {
        int i;
        unsigned char mask = 0x80;
        unsigned char b;
        for (i = 0; i<8; ++i)
        {
            b = (a & mask) ? '1' : '0';
            printf ("%c ",b);
            a <<= 1;
        }
        puts("");
    }
    
    int main ( void )
    {
        int i;
        unsigned char a = 0x57;     /* Beispiel: 01010111 => 11101010 */
        unsigned char b = 0;
        unsigned char mask = 0x80;  /* 10000000 */
    
        println_bin (a);            /* Eingabe */
    
        for (i=0; i<8; ++i)
        {
            if (a & 1) b |= mask;
            mask >>= 1;
            a >>= 1;
        }
    
        println_bin (b);            /* Ergebnis */
        return 0;
    }
    

    Etwa 10 Minuten vorrangig für Tipperei. Wer das nicht aus dem Ärmel schütteln kann, kann nicht programmieren.

    Für welchen Compiler willst Du Inline-Assembler?

    viele grüße
    ralph



  • rkhb schrieb:

    ...
        unsigned char mask = 0x80;
    ...
        for (i = 0; i<8; ++i)
    ...
    

    Du darfst nicht davon ausgehen, dass ein char aus 8 Bit besteht.
    Dafür gibt es extra CHAR_BIT aus limits.h



  • DirkB schrieb:

    Du darfst nicht davon ausgehen, dass ein char aus 8 Bit besteht.
    Dafür gibt es extra CHAR_BIT aus limits.h

    Aufgabenstellung: "Schreiben Sie einen Code der die Bits eines 8 Bit char umdreht."



  • @floorball

    Du musst das bitset natürlich wieder in den char zurückschreiben !! So ist die Aufgabe noch nicht erfüllt.



  • Cool also eine Lösung haben wir ja schon mal. Echt klasse. Und Inline Assembler für Visual Studio Compiler *gg* Keine Ahnung wie der dann heisst.



  • blurry333 schrieb:

    @floorball

    Du musst das bitset natürlich wieder in den char zurückschreiben !! So ist die Aufgabe noch nicht erfüllt.

    Laut Aufgabenstellung nicht!

    blurry333 schrieb:

    Schreiben Sie einen Code der die Bits eines 8 Bit char umdreht

    Und das habe ich ganz klar erfüllt, schließlich sind in meinem bitset bits2 die 8 Bits des chars umgedreht



  • ok nach 3 Stunden refactoring habe ich folgende lösung:

    char reverseBits8(char from)
    {
    	char to = 0;
    	int i=0;
    	for(; i < 8; i++) {
    		if(from & (1 << i)) {
    			to |= 1 << (7 - i);
    		}
    	}
    	return to;
    }
    


  • Du sollst die bits des char umdrehen !! Des char !!!



  • blurry333 schrieb:

    Du sollst die bits des char umdrehen !! Des char !!!

    besser?

    char reverseBits8(char from)
    {
    	char table[256];
    	unsigned int ak = 0;
    	for(; ak <= 255; ak++) {
    		table[ak]=0;
    		int i=0;
    		for(; i < 8; i++) {
    			if(ak & (1 << i)) {
    				table[ak] |= 1 << (7 - i);
    			}
    		}
    
    	}
    	return table[(unsigned char)from];
    }
    


  • blurry333 schrieb:

    Cool also eine Lösung haben wir ja schon mal. Echt klasse. Und Inline Assembler für Visual Studio Compiler *gg* Keine Ahnung wie der dann heisst.

    Ich nenne ihn dann immer MSVC (Microsoft Visual C/C++), die Executable heißt "cl.exe". Inline Assembler gibt es nur für die 32-Bit-Version:

    #include <stdio.h>
    
    void println_bin (unsigned char a)
    {
        int i;
        unsigned char mask = 0x80;
        unsigned char b;
        for (i = 0; i<8; ++i)
        {
            b = (a & mask) ? '1' : '0';
            printf ("%c ",b);
            a <<= 1;
        }
        puts("");
    }
    
    int main ( void )
    {
        unsigned char a = 0x57;     /* Beispiel: 01010111 => 11101010 */
        unsigned char b;
    
        println_bin (a);            /* Eingabe */
    
        __asm {
            movzx eax, a
            mov ecx, 8
            L:
            shr al, 1
            rcl ah, 1
            loop L
            mov b, ah
        }
    
        println_bin (b);            /* Ergebnis */
        return 0;
    }
    

    viele grüße
    ralph



  • Ja. Aufgabe gelöst 🙂



  • Eine Frage hätt ich noch. Ich hab hier einen Intel Prozessor. Versteht der den Assembler Code oder muss der noch mal geändert werden ?



  • Hier noch eine Version, die
    1. Als Funktion ausgelegt ist
    2. Die Bits der Variable umdreht

    void reverse(unsigned char *a)
    {
        unsigned char tmp=0; 
        for(unsigned int mask=1; mask<=0x80; mask<<=1) { 
            tmp = (tmp << 1) | ((*a & mask) != 0); 
        } 
        *a = tmp;
    }
    

    Es ist zwar eigentlich sinnfrei, aber zur Übung auch die ASM-Version:

    void reverse(unsigned char *a)
    {
    __asm{
        xor         cl,cl      ;tmp
        mov         eax,1      ;mask
        mov         ebx,dword ptr [a]  ;Adresse a
        mov         edi,edi  
    label1:
        movzx       edx,byte ptr [ebx]
        test        al,dl  
        setne       dl  
        add         cl,cl      ;tmp<<1
        add         eax,eax    ;mask<<1 
        or          cl,dl      ;tmp = tmp | ...
        cmp         eax,80h    ;mask<=0x80 ?
        jbe         label1
    
        mov         byte ptr [ebx],cl  ;*a=tmp
        }
    }
    

    Da inline ASM bei x64 nicht unterstützt wird, wäre es evtl.
    besser das in eine getrennte Datei zu packen.



  • DirkB schrieb:

    knivil schrieb:

    blurry333 schrieb:

    Lol sobald man ein array hat gehts schon leichter. Aber probiers mal ohne. sondern mit >> Operator . Ich hab noch keine Lösung. Also mit bitset ist es schon leicht klar.

    Lookup table ...

    Die man mit einem C-Programm generiert 😃

    Ich weiss nicht, ieviele Eintraege deine Lookup-Tabelle hat, aber meine haette 16. Die wuerde ich per Hand generieren.



  • knivil schrieb:

    Ich weiss nicht, ieviele Eintraege deine Lookup-Tabelle hat, aber meine haette 16. Die wuerde ich per Hand generieren.

    256 Einträge (bei 8-Bit char). Soll doch schnell gehen. 😃



  • Die Fragen kann jetzt dumm sein, aber ist der Assembler Code jetzt nun für den Compiler oder auch für den Prozessor. Kurzum versteht sowohl Intel als auch AMD diesen Assembler Code ?



  • Der Compiler übernimmt den Code in seine Assemblerausgabe und diese wird dann vom Assembler übersetzt.

    Der Assemblercode ist für die x86 Architektur.

    Die Frage nach "Intel als auch AMD " ist insofern nicht ganz richtig, da diese auch andere Architekturen herstellen/hergestellt haben.

    Für z.B. ARM oder AVR wird der Code nicht funktionieren. (Auch diese Hersteller haben verschiedene Architekturen).

    Aus diesem Grund gibt es ja C. Damit man ein Programm auf verschiedenen Systemen nutzen kann.


Anmelden zum Antworten