Schöne Aufgabe



  • 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.



  • Achja, verschiedene Systeme:

    #include <limits.h>
    
    char reversec(char s)
    {
         int i;
         char d=0;
    
         for( i=0; i<CHAR_BIT ;i++,s >>= 1)
         { d <<=1;
           if (s&1) d|=1;
    
         }
         return d;
    }
    

    Sollte gehen, für jeden Wert von CHAR_BIT.



  • Aso die Amd sind ja x86 kompatibel. Der Befehlssatz von AMD ist wohl dem Intel sehr ähnlich und verwendet dieselbe Registerbezeichnung.



  • DirkB schrieb:

    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. 😃

    Und meine haette waere eben nur 4 Bit mit 16 Eintraegen. Die 2 Nibbles zu vertauschen und zu invertieren nehme ich in Kauf, wenn ich nur eine Lookup-Tabelle mit 16 Eintraegen generieren muss.



  • #include <stdio.h>
    
    typedef unsigned char byte_t;
    const int bitsPerByte=8;
    
    //------------------------------------------------------
    void printByte(byte_t val)
    {
    	int i;
    
    	for(i=0;i<bitsPerByte;++i)
    	{
    		if(val&(1<<(bitsPerByte-1-i)))
    			printf("1");
    		else
    			printf("0");
    	}
    }
    
    //------------------------------------------------------
    byte_t revByte(byte_t val)
    {
    	int i;
    	byte_t res=0;
    
    	for(i=0;i<bitsPerByte;++i)
    	{
    		byte_t bitSet=val&(1<<i);
    		if(bitSet)
    			res=res|(1<<(bitsPerByte-1-i));
    	}
    
    	return res;
    }
    
    //------------------------------------------------------
    int main(int argc,char** argv)
    {
    	int i;
    
    	for(i=0;i<256;++i)
    	{
    		byte_t res=revByte(i);
    		printByte(i);
    		printf("-->");
    		printByte(res);
    		printf("\n");
    	}
    
    	printf("\n----\n");
    
    	return 0;
    }
    

Anmelden zum Antworten