Just for fun, a little demo showing the use of the PSHUFB instruction, and some macro tricks:
include \masm32\MasmBasic\MasmBasic.inc
SwapBytes MACRO pBytes
if type(pBytes) eq REAL8
movlps xmm0, pBytes
else
mov edx, pBytes
movups xmm0, oword ptr [edx]
endif
mov eax, esp
and esp, -16
push 00010203h ; the magic numbers
push 04050607h
push 08090a0bh
push 0c0d0e0fh
PSHUFB xmm0, oword ptr [esp] ; shuffle the bytes! (will crash on very old CPUs, sorry...)
movups oword ptr [esp], xmm0
if type(pBytes) eq REAL8
fld qword ptr [esp]
xchg eax, esp
EXITM <ST(0)> ; leave the double in the FPU
else
xchg eax, esp
EXITM <> ; the bytes are in xmm0, but the macro is not used as a function
endif
ENDM
.data
MyReal8 REAL8 1234567890.1234567890
thestring db "!taerg si 23msaM", 0
.data?
SwappedR8 REAL8 ?
out$ db 20 dup(?)
Init
PrintLine "Original:", Tb$, offset thestring
SwapBytes(offset thestring) ; return 16 bytes in xmm0
movups oword ptr out$, xmm0
PrintLine "Swapped:", Tb$, offset out$
Print Str$("\nMyReal8 \t%Hf", MyReal8), Str$("\nas BigEndian\t%Hf", SwapBytes(MyReal8)) ; SwapBytes leaves the double in the FPU
fstp SwappedR8
Inkey Str$("\nreconverted\t%Hf\n", SwapBytes(SwappedR8)v)
EndOfCode
Note that the macro can be used either as a function:
Print Str$(SwapBytes(MyReal8))
or "standalone":
SwapBytes(offset thestring)
Output:Original: !taerg si 23msaM
Swapped: Masm32 is great!
MyReal8 1234567890.1234567
as BigEndian 3.5842524504192598e+246
reconverted 1234567890.1234567