Bits mit MIPS umdrehen?

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.

Woher ich das weiß:Hobby