Bits mit MIPS umdrehen?
Hey, ich lerne gerade mit MIPS zu Programmieren und möchte gerne:
eine reihe von Bits (z.B. 0000 1001 1100 1110 0000 0010 0010 0000)
in der variablen $t0 speichern und dann umdrehen, sodass am ende 0000 0100 0100 0000 0111 0011 1001 in der veriablen $t0 steht, weiß jemand wie man das machen kann ?
Definer umdrehen. Den Wert Invertieren? Verschieben? Die Position der Bits ändern?
also die reihenfolge invertieren, so dass z.B. aus 00101 10100 wird also spielgeln wenn man so will
1 Antwort
Ich kann speziell MIPS Assembly nicht! X86 und ia64 oder amd64 kann ich.
Ich schreibe eine Assemblerfunktion meistens erst, nachdem ich das Prinzip in C bereits umgesetzt habe.
___
Um so eine Funktion umzusetzen, gibt es meistens generell 2 Möglichkeiten.
- Eine Schleife
- eine Lookup-Tabelle
Die "Schleife" Funktion ließe sich in C wie folgt umsetzen:
unsigned int invert_bit_order_loop(unsigned int data)
{
unsigned int result = 0, shift = 8 * sizeof(data) - 1;
while (data)
{
result |= (data & 1) << shift;
data >>= 1;
--shift;
}
return result;
}
Eine Lookup-Tabelle ließe sich in C wie folgt umsetzen:
inline unsigned char invert_bit_order_table_8(unsigned char data);
unsigned int invert_bit_order_table(unsigned int data)
{
unsigned int result = 0, shift = (sizeof(data) - 1) * 8;
while (data)
{
result |= invert_bit_order_table_8(data & 0xFF) << shift;
data >>= 8;
shift -= 8;
}
return result;
}
inline unsigned char invert_bit_order_table_8(unsigned char data)
{
/* This table was generated with the following code:
for (int count = 0; count <= 255; ++count)
{
const int inverted =
invert_bit_order_loop(count) >> (sizeof(int) * 8 - 8);
printf("%d,", inverted);
}*/
static const unsigned char table[256] = {
0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,
8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248,
4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,
12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,
2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,
10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,
6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,
14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,
1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,
9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,
5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,
13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,
3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,
11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251,
7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,
15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255 };
return table[data];
}
Nachdem ich beide Funktionen getestet habe und sie auch funktionieren, kann ich sie in Assembly übersetzen.
Übrigens läuft die Lookup-Tabelle minimal schneller als die Schleife, wie aus einem eigenen Benchmark hervorgegangen ist.
Ich hoffe, ich konnte damit weiterhelfen.