I am asked on HW to reverse bits, like mirror flip them so for example 1011 0100 becomes 0010 1101, using shift and rotate combination. I understand how those commands work but I can't think of a way to flip them. Thanks. I need to do it using SAL assembly language.
-
nor can I. Can you use ANDs and ORs as well? – John Dvorak Oct 27 '12 at 04:40
-
@MattBall 1234 5678 => 2345 6781 is a left rotation by one. – John Dvorak Oct 27 '12 at 04:41
-
@JanDvorak not sure how that's different from "shift." – Matt Ball Oct 27 '12 at 04:45
-
Removed homework tag as it has been [deprecated](http://meta.stackexchange.com/questions/147100/the-homework-tag-is-now-officially-deprecated). – Some programmer dude Oct 27 '12 at 04:51
-
1Try looking at [this question](http://stackoverflow.com/questions/4924060/reverse-a-byte-using-assembly-language), for a start – ThatOtherPerson Oct 27 '12 at 04:53
-
@MattBall Logical shift inserts zeroes, arithmetical left shift copies the highest bits, shift from carry inserts the carry flag, rotate shifts in what is shifted out... – John Dvorak Oct 27 '12 at 05:00
1 Answers
If you need to flip a b-bit word using only shifts, you could emulate a stack:
b times{
right shift on the input register, setting a carry flag.
left shift on the output register, reading the carry flag.
}
Note that x86 has the "rotate through carry" instructions - they serve both purposes (or use rotation without carry on the input register to preserve the input). If left shift from carry is not available but right shift from carry is, reverse the words "left" and "right" in the previous algorithm. If no shift from carry is available, you need to emulate by an "ordinary" logical shift followed by setting the correct bit, but...
If you can use AND and OR as well and b is known ahead and is a power of two, there is a faster way. Reverse two bits within each pair, then two pairs within each nibble, then two nibbles within each byte, then two bytes within each word...
for 8-bit x:
//1234 5678
x = (0x55 & x)<< 1 | (0xAA & x)>> 1 //2143 6587
x = (0x33 & x)<< 2 | (0xCC & x)>> 2 //4321 8765
x = (0x0F & x)<< 4 | (0xF0 & x)>> 4 //8765 4321

- 26,799
- 13
- 69
- 83