There is a special opcode for this, called BSWAP
, for example:
MOV EAX,1 ; EAX is 0x00000001 or 1 decimal
BSWAP EAX ; EAX is 0x01000000 or 16777216 decimal
It will swap all 4 bytes of any 32 bit general purpose register. This converts little-endian 32 bit values to big-endian and vice versa.
FWIW, to swap the bytes of a 16 bit value, e.g. in AX
, you can do
MOV AX,1 ; AX is 0x0001 or 1 decimal
XCHG AL,AH ; AX is 0x0100 or 256 decimal
Or, according to @PeterCordes:
MOV AX,0x1234
ROL AX,8 ; AX is 0x3412 now
There is no special opcode to swap only the top and low bytes of a 32 bit register (and leave the other two intact). You can only do something like this:
Edit
<removed code using ROR
, XCHG AL,AH
, ROL
and BSWAP
>
As @Fifoernik pointed out in a comment (thanks!), much easier than the code I removed is the following:
MOV EAX,0x12345678
ROL EAX,8 ; EAX is 0x34567812 rotate left one byte: 12 34 56 78 --> 34 56 78 12
XCHG AL,AH ; EAX is 0x34561278 swap 12 and 78: 34 56 78 12 --> 34 56 12 78
ROR EAX,8 ; EAX is 0x78345612 rotate back: 34 56 12 78 --> 78 34 56 12
Edit 2
As @PeterCordes points out, this might even be a little faster:
MOV EAX,0x12345678
ROL EAX,8 ; EAX is 0x34567812 rotate left one byte: 12 34 56 78 --> 34 56 78 12
ROL AX,8 ; EAX is 0x34561278 swaps 12 and 78: 34 56 78 12 --> 34 56 12 78
ROR EAX,8 ; EAX is 0x78345612 rotate back: 34 56 12 78 --> 78 34 56 12
But I didn't time either of those.