-2

we start with a 32 bit code e.g: "AA BB CC DD" (little endian)

we want "AA DD CC BB" as end result (big endian). I've managed to write it in 8 lines, with %ebx as the entry and %ecx as the exit. The teacher mentioned it was possible to write this in less than 4 lines, 3 being the record. I was curious to see how it can be shortened.

mov %R1, %ebx 
mov %bx, %cx 
shl $16, %ecx
mov %cl, %dl
mov %bl, %cl
mov %bh, %dh
shr %16, %edx
and %edx, %ecx
P. Diddy
  • 21
  • 1
  • Yes, it is possible to do this with three instructions. But I refrain from being sadistic. I neither want you to put your fellow students down nor do I you want you to prematurely give up on learning assembly. **Assembly is fun'**. Study the instructions of `x86` assembly and you will probably find a better solution. Here you'll find a good [starting point](http://www.felixcloutier.com/x86). – zx485 Apr 09 '16 at 16:08
  • Maybe I am misreading this question, but I don't see how AA DD CC BB is the big endian form of AA BB CC DD. – Michael Petch Apr 09 '16 at 16:15
  • @Michael Petch: You don't see it, because it's not there. It's big-endian converted to little-endian **`ROR'ed` by one byte**. – zx485 Apr 09 '16 at 17:23
  • @zx485: implementing bswap in 3 instructions is straightforward with 16bit and 32bit rotates, but I don't see how to implement this bswap + ror with 3 total insns, without using `bswap` (since that would be 2 insns). Is it possible with just rotates? Do you need a 2nd register for `shrd ebx,eax, 16` / `mov bx,ax` or something (can't see how that helps)? I'm assuming `movd` / `pshufb xmm0, [mask]` / `movd` isn't allowed either. – Peter Cordes Apr 10 '16 at 01:39
  • You can write multiple instructions on a single line in AT&T syntax with `;` as a separator. `ror $16, %eax; ror $8, %ax`, for example. Obviously you meant to ask about instructions, not lines, though. – Peter Cordes Apr 10 '16 at 02:40
  • @Peter Cordes: I'm not sure why you would want to implement `bswap` with other instructions. The perfect solution, given in the answer below, is three instructions: `mov %R1, %eax; bswap %eax; ror $8, %eax`. For example, I thought about an implementation using `xchg %al, %ah ...`, but since the solution with `bswap` is optimal, I aborted that thought. I guess that this professor wanted to guide his students ability to acquire the knowledge of and capability of using an (x86) instruction set. IMHO an honorable aim. – zx485 Apr 10 '16 at 09:01
  • @zx485: why? Because it's an interesting challenge which I thought people were claiming was possible. I didn't realize the 3rd insn was just a `mov` to make it non-destructive, since the OP was not at all clear that the result couldn't just be in the same reg as the source. If the source was in memory, you could do it with two insns (on Haswell/Silvermont or later): `movbe (mem), %eax; ror $8, %eax`. – Peter Cordes Apr 10 '16 at 16:07
  • Or if the dest can be in memory, then two instructions including an inefficient `ror` with a memory operand: `movbe %R1, (mem); ror $8, (mem)`. – Peter Cordes Apr 10 '16 at 16:24

1 Answers1

3

I'm not certain of the att syntax, but you can do

bswap ebx    ; AA BB CC DD -> DD CC BB AA     Swap byte order
ror ebx, 8   ; DD CC BB AA -> AA DD CC BB     Roll right 8 bits
Mitch
  • 21,223
  • 6
  • 63
  • 86
  • You took the fun out of it. Nevertheless, I have to give you a vote. – zx485 Apr 09 '16 at 16:09
  • 2
    Happy to help :) Oh! that wasn't sarcastic. I am happy to handicap any exercise that doesn't start with "Of course, you'd never do this in real life, since there is a handy `bswap` instruction. I've had to retrain too many CS students that reimplement quicksort instead of using a tested library... – Mitch Apr 09 '16 at 16:18