Passing parameters to invoke
----------------------------
If you are on the way of size and speed optimization
(wich is actually easier then in any HLL)
first thing you need to set easy methods to
culculate speed and size.
Without it all you do will be something close to
speculations.
If it will not easy way - then your work will be hard and
uneffective.
But with easy methods it becomes most fun and exciting game.
-------------
One of common mistakes in the writing HLL imitation in asm
is to use local variables to pass parameters in invoke
though those parameters are already in some regs and may be
pushed in memory for it.
To get clear picture of what the difference is let's recall
simple and wellknown things.
invoke SomeFunc,LocalVariable
will result in
push
call SomeFunc.
push is 3 bytes size and 2 clocks speed and NP!
push reg is 1 byte size 1 byte speed and UVP! (thats mean if
code in pipes you can perform additional operation whithin one clock
if two operations are pareble)
-----------------------------
To illustrate it let's have a look at the FrameWindow proc from M32LIB
FrameWindow proc hndle:DWORD, step:DWORD, wid:DWORD, direction:DWORD
; -------------------------------------------------------------
; This proc is used for framing the client area of a window.
; Parameters.
; 1. The handle of the window.
; 2. step, the distance from the inside edge of the client area
; in pixels to draw the frame
; 3. wid, the width of the frame in pixels.
; 4. direction, 0 = sunken frame, 1 = raised frame.
; -------------------------------------------------------------
LOCAL btn_hi :DWORD ;it's local variable
LOCAL btn_lo :DWORD ;it's not bad thing actually to create them
LOCAL hDC :DWORD ;To get space for them we need just one oneclock
LOCAL Rct :RECT ;instruction no matter how many of them we need
invoke GetDC,hndle ;push hndle 3 bytes, 2 clocks
mov hDC, eax
invoke GetClientRect,hndle,ADDR Rct
;lea eax, - 3bytes 1 clock
;push eax - 1 byte 1 clock
;push hndle - 3 bytes ,2 clocks
;and so on.....
mov eax, step
mov edx, wid
add eax, edx
add Rct.left, eax
add Rct.top, eax
inc eax
sub Rct.right, eax
sub Rct.bottom, eax
invoke GetSysColor,COLOR_BTNHIGHLIGHT
mov btn_hi, eax
invoke GetSysColor,COLOR_BTNSHADOW
mov btn_lo, eax
.if direction == 1
mov eax, btn_lo
mov ecx, btn_hi
mov btn_lo, ecx
mov btn_hi, eax
.endif
invoke Frame3D,hDC,btn_lo,btn_hi,
Rct.left,
Rct.top,Rct.right,Rct.bottom,wid
invoke ReleaseDC,hndle,hDC
ret
FrameWindow endp
; #########################################################################
Lets see if we can decrease number of locals pushes using values
in regs.
(Mind we get 1(+1) clock speed and 2 clocks size decrise for each of
those replacements + we for instructions we need to put values in the
locals)
A little bit optimized version of FrameWindow
FrameWindow proc hndle:DWORD, step:DWORD, wid:DWORD, direction:DWORD
; -------------------------------------------------------------
; This proc is used for framing the client area of a window.
; Parameters.
; 1. The handle of the window.
; 2. step, the distance from the inside edge of the client area
; in pixels to draw the frame
; 3. wid, the width of the frame in pixels.
; 4. direction, 0 = sunken frame, 1 = raised frame.
; -------------------------------------------------------------
; LOCAL btn_hi :DWORD
; LOCAL btn_lo :DWORD
LOCAL hDC :DWORD
LOCAL Rct :RECT
invoke GetDC,hndle
mov hDC, eax
invoke GetClientRect,hndle,ADDR Rct
mov eax, step
mov edx, wid
add eax, edx
add Rct.left, eax
add Rct.top, eax
inc eax
sub Rct.right, eax
sub Rct.bottom, eax
This is one of the main reasons I don't like PROC/INVOKE and the local varible mechanism that exists. I will be using MACROs as much as I can to rename the registers - this makes the code very readable (see my QuickSort PROC for an example of this). Also there are many times when I don't want to give up the EBP register. MASM builds a stack frame even if I don't have local varibles: it must reference local and passed varibles through EBP - I don't like this. :(
I do understand why this is so, but there should be more fexiblity, don't you think?
Svin, great comments here and on the other threads. I always enjoy reading your posts/code.