uLib  User mode C/C++ extended API library for Win32 programmers.
_bswap.asm
Go to the documentation of this file.
1 ;==----------------------------------------------------------------------------
2 ; Efficient _bswap16/32/64 implementations.
3 ; Dual mode (32/64 bit) assembly source.
4 ; Copyright (c) Love Nystrom
5 ;==----------------------------------------------------------------------------
6 
7 TITLE Efficient _bswap16/32/64 implementations for 32 and 64 bit targets.
8 
9 IFDEF RAX
10  _WIN64 = 1
11 ELSE
12  _WIN64 = 0
13  .686P ; Change this if you need to
14  .XMM ; Change this if you need to
15  .MODEL FLAT
16 ENDIF
17 
18 ;==============================================================================
19 ; Common x86/x64 - Constants and parameterless functions
20 ;==============================================================================
21 
22 _TEXT SEGMENT
23 ; No common code or data.
24 _TEXT ENDS
25 
26 ;==============================================================================
27 IF (_WIN64 eq 0) ; 32 bit version
28 ;==============================================================================
29 ECHO === 32-BIT ASSEMBLY (ML) ===
30 
31 _TEXT SEGMENT
32 
33 ;; Vanilla byte order swappers (x86)
34 
35 PUBLIC __bswap16 ; extern "C" UINT16 _cdecl _bswap16( UINT16 W )
36 PUBLIC __bswap32 ; extern "C" UINT32 _cdecl _bswap32( UINT32 Val )
37 PUBLIC __bswap64 ; extern "C" UINT64 _cdecl _bswap64( UINT64 Val )
38 
39 __bswap16 PROC
40  mov ax, word ptr [esp+4]
41  xchg al, ah
42  ret
43 __bswap16 ENDP
44 
45 __bswap32 PROC
46  mov eax, dword ptr [esp+4]
47  bswap eax
48  ret
49 __bswap32 ENDP
50 
51 __bswap64 PROC
52  mov edx, dword ptr [esp+4]
53  mov eax, dword ptr [esp+8]
54  bswap eax
55  bswap edx
56  ret
57 __bswap64 ENDP
58 
59 ;; COLORREF / RGBQUAD byte order swappers (x86)
60 
61 PUBLIC __swapRGB ; extern "C" DWORD __cdecl _swapRGB( DWORD rgb );
62 PUBLIC __swapRGB2 ; extern "C" DWORD __cdecl _swapRGB2( DWORD rgb );
63 
64 __swapRGB PROC ; Preserves the high byte
65  mov eax, dword ptr [esp+4]
66  mov edx, eax
67  bswap eax
68  shr eax, 8 ; bgr
69  and edx, 0FF000000h
70  or eax, edx
71  ret
72 __swapRGB ENDP
73 
74 __swapRGB2 PROC ; Clears the high byte
75  mov eax, dword ptr [esp+4]
76  bswap eax
77  shr eax, 8 ; bgr
78  ret
79 __swapRGB2 ENDP
80 
81 _TEXT ENDS
82 
83 ;==============================================================================
84 ELSE ; 64 bit version
85 ;==============================================================================
86 ECHO === 64-BIT ASSEMBLY (ML64) ===
87 
88 ; Extern C assembly routines does NOT get an added underscore with MSVC + ML64.
89 ; Hence the x64 assembly routines must be named *_exactly as the C prototypes_*.
90 ;
91 ; Fastcall is used regardless of prototype declaration!
92 ; Arguments -> RCX, RDX, R8, R9, then stack.
93 ;
94 ; The four register args are backed by unused stack cells.
95 ; Ergo, after std prologue the fifth argument is at [RBP+48].
96 ;
97 ; Normal fastcall stack cleanup convention (function pop args) is *not used*.
98 ; Functions end with 'ret 0' even if they had stack args.
99 ;
100 ; RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile.
101 ; RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are nonvolatile
102 ; and must be saved and restored by a function that use them.
103 ;
104 ; frame$ = 10h ; Offset from rbp to first shadow arg after 'enter 0,0'
105 ; x64 fastcall arguments:
106 ; rcx = arg1 (rbp+10h)
107 ; rdx = arg2 (rbp+18h)
108 ; r8 = arg3 (rbp+20h)
109 ; r9 = arg4 (rbp+28h)
110 ; [rbp+30h] = arg5 (rbp+30h)
111 
112 _TEXT SEGMENT
113 
114 ;; Vanilla byte order swappers (x64)
115 
116 PUBLIC _bswap16 ; extern "C" UINT16 _bswap16( UINT16 W )
117 PUBLIC _bswap32 ; extern "C" UINT32 _bswap32( UINT32 Val )
118 PUBLIC _bswap64 ; extern "C" UINT64 _bswap64( UINT64 Val )
119 
120 _bswap16 PROC
121  mov ax, cx
122  xchg al, ah
123  ret
124 _bswap16 ENDP
125 
126 _bswap32 PROC
127  mov eax, ecx
128  bswap eax
129  ret
130 _bswap32 ENDP
131 
132 _bswap64 PROC
133  mov rax, rcx
134  bswap rax
135  ret
136 _bswap64 ENDP
137 
138 ;; COLORREF / RGBQUAD byte order swappers (x64)
139 
140 PUBLIC _swapRGB ; extern "C" DWORD __cdecl _swapRGB( DWORD rgb );
141 PUBLIC _swapRGB2 ; extern "C" DWORD __cdecl _swapRGB2( DWORD rgb );
142 
143 _swapRGB PROC ; Preserves the high byte
144  mov eax, ecx
145  bswap eax
146  shr eax, 8 ; bgr
147  and ecx, 0FF000000h
148  or eax, ecx
149  ret
150 _swapRGB ENDP
151 
152 _swapRGB2 PROC ; Clears the high byte
153  mov eax, ecx
154  bswap eax
155  shr eax, 8 ; bgr
156  ret
157 _swapRGB2 ENDP
158 
159 _TEXT ENDS
160 
161 ENDIF ; _WIN64
162 END