Reputation: 154
So I figured out how to reverse the endianess of a four byte long int in C:
unsigned int swapWord (unsigned int n){
return (n>>24) | ((n<<8) & 0x00FF0000) |((n>>8) & 0x0000FF00) | (n<<24);
}
Now I know I can just disassemble this, and I did, and it was decent code, but I'm sure there is a more efficient way to reverse the endianess. Any ideas?
Edit: Here's the disassembled code:
00000000004005a3 <swapWord>:
4005a3: 55 push %rbp
4005a4: 48 89 e5 mov %rsp,%rbp
4005a7: 89 7d fc mov %edi,-0x4(%rbp)
4005aa: 8b 45 fc mov -0x4(%rbp),%eax
4005ad: c1 e8 18 shr $0x18,%eax
4005b0: 89 c2 mov %eax,%edx
4005b2: 8b 45 fc mov -0x4(%rbp),%eax
4005b5: c1 e0 08 shl $0x8,%eax
4005b8: 25 00 00 ff 00 and $0xff0000,%eax
4005bd: 09 c2 or %eax,%edx
4005bf: 8b 45 fc mov -0x4(%rbp),%eax
4005c2: c1 e8 08 shr $0x8,%eax
4005c5: 25 00 ff 00 00 and $0xff00,%eax
4005ca: 09 c2 or %eax,%edx
4005cc: 8b 45 fc mov -0x4(%rbp),%eax
4005cf: c1 e0 18 shl $0x18,%eax
4005d2: 09 d0 or %edx,%eax
4005d4: 5d pop %rbp
4005d5: c3 retq
4005d6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4005dd: 00 00 00
Upvotes: 2
Views: 3552
Reputation: 37222
For 80486 and later, there's an instruction called bswap
that swaps bytes in a dword.
For older 80386 CPUs I'd be tempted to use something like this:
;eax = 0xAABBCCDD
xchg ah,al ;eax = 0xAABBDDCC
rol eax,16 ;eax = 0xDDCCAABB
xchg ah,al ;eax = 0xDDCCBBAA
For even older CPUs (8086 to 80286) you have to use a pair of 16-bit registers (as there are no 32-bit registers), and it ends up like this:
;dx:ax = 0xAABBCCDD
;ax:dx = 0xCCDDAABB
xchg ah,al ;ax:dx = 0xDDCCAABB
xchg dh,dl ;ax:dx = 0xDDCCBBAA
Note: Instead of using xchg ah,al
you could use either ror ax,8
or rol ax,8
. I doubt it makes much difference which of these 3 instructions you use.
Upvotes: 5