Skip to content

Instantly share code, notes, and snippets.

Created December 16, 2016 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4026d9d4aecf06ef39a3dac655c3e69e to your computer and use it in GitHub Desktop.
Save anonymous/4026d9d4aecf06ef39a3dac655c3e69e to your computer and use it in GitHub Desktop.
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