Created
December 16, 2016 14:12
-
-
Save anonymous/4026d9d4aecf06ef39a3dac655c3e69e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Public Function RGBToHex(ByVal color As Long) As String | |
;; Prologue code that is generated automatically for functions by VB 6, | |
;; and doesn't correspond to any code that we actually wrote. | |
;; There's nothing we can do to optimize this! | |
push ebp | |
mov ebp,esp | |
sub esp,0Ch | |
push offset ___vbaExceptHandler | |
mov eax,dword ptr fs:[00000000h] | |
push eax | |
mov dword ptr fs:[0],esp | |
sub esp,38h | |
push ebx | |
push esi | |
push edi | |
mov dword ptr [ebp-0Ch],esp | |
mov dword ptr [ebp-8],offset __imp____vbaFreeObj+4Ch | |
xor ebx,ebx | |
mov dword ptr [ebp-4],ebx | |
mov eax,dword ptr [Me] | |
mov ecx,dword ptr [eax] | |
push eax | |
call dword ptr [ecx+4] | |
;; The following instructions correspond to our VB code that isolates the individual color | |
;; components. Although this code isn't perfectly optimal, which is rather disappointing | |
;; from the perspective of an optimization nerd, it is the best we can get out of VB 6. | |
;; Note the use of simple and fast arithmetic adds and bitwise shifts, since I turned on | |
;; the "Remove Integer Overflow Checks" option. | |
; r = (color And &HFF) | |
mov edi,dword ptr [color] | |
mov edx,dword ptr [RGBToHex] | |
mov dword ptr [edx],ebx | |
; g = ((color \ &H100) And &HFF) | |
mov eax,edi | |
cdq | |
and edx,0FFh | |
add eax,edx | |
mov esi,eax | |
; b = ((color \ &H10000) And &HFF) | |
mov eax,edi | |
cdq | |
and edx,0FFFFh | |
add eax,edx | |
mov ecx,edi | |
and ecx,0FFh | |
sar esi,8 | |
; color = ((r * &H10000) + (g * &H100) + b) | |
mov edx,ecx | |
shl edx,8 | |
and esi,0FFh | |
add edx,esi | |
sar eax,10h | |
and eax,0FFh | |
shl edx,8 | |
add edx,eax | |
;; These instructions correspond to the 'If' statement, and the formatting of the string. | |
;; | |
;; Here is where we start getting into truly horrific, sub-optimal code. I haven't the foggiest | |
;; idea why the compiler insists on generating multiple, redundant instructions to store the | |
;; value of the EBX register into 'unnamed_var1'. Doing it once would be pointless enough, but | |
;; doing it repeatedly is just sheer nonsense! Maybe this is supposed to be padding, but there | |
;; are simpler and more appropriate filler instructions that can be used for padding. | |
;; (And there's no reason for these sections of code to be padded out anyway!) | |
;; | |
;; Aside from that, you can see all of the 'call' instructions here, which call helper functions | |
;; from the VB 6 runtime library. They are nearly all string-related ('Str*'), which gives you | |
;; some clue as to why I was ranting so much about how horribly expensive string operations are! | |
; If (r >= &H10) Then | |
cmp ecx,10h ; do the comparison | |
mov dword ptr [RGBToHex],ebx | |
mov dword ptr [unnamed_var1],ebx | |
mov dword ptr [unnamed_var1],ebx | |
mov dword ptr [unnamed_var1],ebx | |
mov dword ptr [unnamed_var1],ebx | |
mov dword ptr [color],edx | |
jl NeedsPadding ; jump to 'NeedsPadding' if less, fall through otherwise | |
; RGBToHex = Hex$(color) | |
lea ecx,[unnamed_var1] | |
lea eax,[color] | |
push ecx | |
mov dword ptr [ebp-38h],eax | |
mov dword ptr [unnamed_var1],4003h | |
call dword ptr [__imp____vba@00212454] | |
mov edx,eax | |
lea ecx,[RGBToHex] | |
call dword ptr [__imp____vbaStrMove] | |
jmp Finished ; jump directly to 'Finished' | |
NeedsPadding: | |
; Else | |
; RGBToHex = Right$("00000" & Hex$(color), 6) | |
lea eax,[unnamed_var1] | |
lea edx,[color] | |
push eax | |
mov dword ptr [ebp-38h],edx | |
mov dword ptr [unnamed_var1],4003h | |
call dword ptr [__imp____vba@00212454] | |
mov esi,dword ptr [__imp____vbaStrMove] | |
mov edx,eax | |
lea ecx,[unnamed_var1] | |
call esi | |
mov edx,dword ptr [unnamed_var1] | |
push 6 | |
push offset ___vba@001C90A0 | |
lea ecx,[unnamed_var1] | |
mov dword ptr [unnamed_var1],ebx | |
call esi | |
push eax | |
call dword ptr [__imp_@__vbaStrCat] | |
mov edx,eax | |
lea ecx,[unnamed_var1] | |
call esi | |
push eax | |
call dword ptr [__imp____vba@03CC1EC8] | |
mov edx,eax | |
lea ecx,[RGBToHex] | |
call esi | |
lea ecx,[unnamed_var1] | |
push ecx | |
lea edx,[unnamed_var1] | |
push edx | |
lea eax,[unnamed_var1] | |
push eax | |
push 3 | |
call dword ptr [__imp_@__vbaFreeStrList] | |
add esp,10h | |
;; Epilogue code that is generated automatically for functions by VB 6. | |
;; Like the prologue code, this doesn't correspond to anything that we actually wrote, | |
;; and so it is unavoidable and unoptimizable. | |
Finished: | |
mov eax,dword ptr [Me] | |
mov ecx,dword ptr [eax] | |
push eax | |
call dword ptr [ecx+8] | |
mov eax,dword ptr [RGBToHex] | |
mov edx,dword ptr [RGBToHex] | |
mov dword ptr [edx],eax | |
mov eax,dword ptr [ebp-4] | |
mov ecx,dword ptr [ebp-14h] | |
pop edi | |
pop esi | |
mov dword ptr fs:[0],ecx | |
pop ebx | |
mov esp,ebp | |
pop ebp | |
ret 0Ch | |
End Function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment