I'm constructing the ddraw.dll vtable:
I know this is a silly place to optomize, as It is only done on startup. I would like to know if there are and what kind of penalties there are between version 1 and version 2. Would like to learn a little something about more in-depth otomization.
Thanks.
invoke DirectDrawCreate, 0,ADDR lpDD ,0
lea edx, lpDD
mov edx, [edx];not to sure about this part
mov edx, [edx]
mov eax, edx;store vtable address in eax
mov edx, [edx];start storing the table!!!
mov [lpDD+4], edx
add eax, 4
mov edx, eax
mov edx, [edx]
mov [lpDD+8], edx
add eax, 4
mov edx, eax
mov edx, [edx]
mov [lpDD+12], edx
add eax, 4
mov edx, eax
.
.
.
or would this be better?:
invoke DirectDrawCreate, 0,ADDR lpDD ,0
lea edx, lpDD
mov eax, [edx];not to sure about this part
mov edx, [eax]
mov eax, edx;store vtable address in eax
mov ecx, [edx];Using another reg this time
mov [lpDD+4], ecx
add eax, 4
mov edx, eax
mov ecx, [edx]
mov [lpDD+8], ecx
add eax, 4
mov edx, eax
mov ecx, [edx]
mov [lpDD+12], ecx
add eax, 4
mov edx, eax
.
.
I know this is a silly place to optomize, as It is only done on startup. I would like to know if there are and what kind of penalties there are between version 1 and version 2. Would like to learn a little something about more in-depth otomization.
Thanks.
Just discovered TEXTEQU
QueryInterface TEXTEQU<lpDD+4>
AddRef TEXTEQU<lpDD+8>
Release TEXTEQU<lpDD+12>
mov edx, [edx]
mov [QueryInterface], edx
add eax, 4
mov edx, eax
mov edx, [edx]
mov [Addref], edx
add eax, 4
mov edx, eax
mov edx, [edx]
mov [Release], edx
add eax, 4
mov edx, eax
I don't know what your trying to do, but it doesn't look right? :tongue: Why not just use the indirection? Store just the interface pointer - it is required for the call.
I'm string the address to call for each of the DirectDraw funtions in order. I have no inc file for the funtions in the vtable. I'm using the ddraw.inc that comes with MASM32, which provides no functionality to call the vtable functions without traversing the pointer to the address to call for each function. Since I have to find the address myself, I might as well just rebuild the table. Then I can use real names(remember no inc to provide this):
Yes, I probably could just use the vtable provided by the dll, but I think I can make the code cleaner this way. I've tested my vtable and the calls work, using call indirect. I guess my real question is about register usage:
Thanks.
_QueryInterface dword 0;(lpDD+QueryInterface)
_AddRef dword 0
_Release dword 0
Yes, I probably could just use the vtable provided by the dll, but I think I can make the code cleaner this way. I've tested my vtable and the calls work, using call indirect. I guess my real question is about register usage:
invoke DirectDrawCreate, 0,ADDR lpDD ,0
lea edx, lpDD
mov edx, [edx]
mov edx, [edx];is there some sort of penalty for using
;regs this way? same reg again and
mov eax, edx ;again? Is it better totry to use
mov edx, [edx]; different regs?
Thanks.
cleaner code? :rolleyes:
With code like
You're 'trashing' memory after the lpDD variable. If you *really* want
to avoid vtable lookup on method calls, and only do single indirection
(as if the few extra cycles mattered at all), you ought to do it more
cleanly - have variables set aside to store the method pointers... or
perhaps use an array.
If your intention is to put the method pointers inside the lpDD object
(sorta "move it out of the vtable and into the object"), then go take
some medication ;).
With code like
mov [lpDD+4], edx
You're 'trashing' memory after the lpDD variable. If you *really* want
to avoid vtable lookup on method calls, and only do single indirection
(as if the few extra cycles mattered at all), you ought to do it more
cleanly - have variables set aside to store the method pointers... or
perhaps use an array.
If your intention is to put the method pointers inside the lpDD object
(sorta "move it out of the vtable and into the object"), then go take
some medication ;).
f0dder, I'm trying to learn how to make cleaner code. I am trying to find a good clean style that works for me. With the , I'm doing something dirty. This explains it:
I'm taking advantage of the fact that it will assemble like an array of dwords, without the syntax overhead. This method seems logical to me, but I'm still not convinced it is the best way yet. Thanks for the criticism. Do I still need medication? :confused: :grin:
.data
align 16
lpDD dword 0;[lpDD]
_QueryInterface dword 0;[lpDD+4]
_AddRef dword 0;etc
_Release dword 0
_Compact dword 0
.
.
I'm taking advantage of the fact that it will assemble like an array of dwords, without the syntax overhead. This method seems logical to me, but I'm still not convinced it is the best way yet. Thanks for the criticism. Do I still need medication? :confused: :grin:
Nah, no medication :). What you're doing is OK, really... Imo you could
make the source a bit prettier and clearer doing something like this:
And referring to METHODS+xx instead of lpDD+xx.
Also, you could do a memcopy instead of the manual method moving.
make the source a bit prettier and clearer doing something like this:
.data
align 16
lpDD dword 0;[lpDD]
METHODS label dword
_QueryInterface dword 0;[lpDD+4]
_AddRef dword 0;etc
_Release dword 0
_Compact dword 0
...
And referring to METHODS+xx instead of lpDD+xx.
Also, you could do a memcopy instead of the manual method moving.
And referring to METHODS+xx instead of lpDD+xx.
Also, you could do a memcopy instead of the manual method moving.
Also, you could do a memcopy instead of the manual method moving.
Reminds me of my recent post in the MASM section when I discoverd I could use labels in the data section.
You may just be right about using METHODS+xx.... Using TEXTEQU seems more like something for general program usage, whereas METHODS+xx explains better just what the code if for:
mov edx, [edx]
mov [QueryInterface], edx
add eax, 4
mov edx, eax
mov edx, [edx]
mov [Addref], edx
add eax, 4
mov edx, eax
Using real names in the initilization code does not explain very well what the code does. METHODS+xx explains, and(I need time later to code this)may make for shorter, thus cleaner code. Thanks for the tip f0dder:alright:
I'd use "METHODS+xx" (or rather, a single reference to METHODS
in a copymem call) in the initialization, and "nice names" during the code.
I still don't see what the big fuzz about the extra indirection is about,
but oh well, things probably wont break by using your method, and
then it doesn't really matter :).
Well, breakage *could* happen in the (wildly unlikely, imo) event
vtables are patched later on in memory...
in a copymem call) in the initialization, and "nice names" during the code.
I still don't see what the big fuzz about the extra indirection is about,
but oh well, things probably wont break by using your method, and
then it doesn't really matter :).
Well, breakage *could* happen in the (wildly unlikely, imo) event
vtables are patched later on in memory...
Much cleaner.......
Changing for lea to mov let me get rid of one pointer traversal.
Yes, I like the unrolled form. It is only done once at startup.
I'm doing because I have no inc file and I want nice names
:grin:
invoke DirectDrawCreate, 0,ADDR lpDD ,0
mov edx, [lpDD];change from lea edx, lpDD
mov eax, [edx]; get vtable pointer
mov edx, eax;uneeded copy of vtable pointer
mov edx, [eax]
mov METHODS, edx
mov edx, [eax+4]
mov METHODS+4, edx
mov edx, [eax+8]
mov METHODS+8, edx
.
.
Changing for lea to mov let me get rid of one pointer traversal.
Yes, I like the unrolled form. It is only done once at startup.
I'm doing because I have no inc file and I want nice names
:grin:
Create an inc file? :)