My attempt.



.code
start:
align 4

construct PROC

mov ebx, [esp+4] ;SIZEOF OBJECT

invoke GetProcessHeap ;allocate SIZEOF OBJECT from the process heap
invoke HeapAlloc, eax, NULL, ebx

mov ecx, [esp+8] ;number of parms(func/data total)/ HeapAlloc destroys ecx
mov edi, eax ;use edi, save eax for return
mov ebx, 12 ;esp+12 equal the first parm

build:

cmp ecx, 0 ;number of parms == 0? if so:
jz exit ;exit, we want an empty object(why? I don't know)
mov edx,[esp][ebx] ;get a parm from the stack
mov [edi][ebx-12],edx ;the source is esp+12, the destination isn't;)

dec ecx ;1 less parm to construct
jz exit ;done, lets go and return the pointer to our new object!

add ebx, 4 ;increase stack index to next parm
jmp build

exit:

ret ;eax is address of our new object

construct endp

END


usage:



P0 TYPEDEF proto
P1 TYPEDEF proto :DWORD
P2 TYPEDEF proto :DWORD, :DWORD
P3 TYPEDEF proto :DWORD, :DWORD, :DWORD
P4 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD
P5 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
P6 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
P7 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
P8 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
P9 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
P10 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

PP4 TYPEDEF PTR P4

.code
invoke P3 ptr construct, SIZEOF SSTRING, 1, ADDR sstring
;the first parm is the size of your structure
;the second i the number of parms
;the last is the address of a function my object will contain
;eax = the address of the object

invoke PP4 ptr [eax], eax, 1, 4096, 8192

;this last line is another converation
;but it is a working test for my string class
;creating a pointer in my class to a dynamically allocated string
;allocated by the method sstring


Edit: I should explain better what this does:
It get memory, and will put the paramters given on the stack. You dont have to build the entire object. If you dont know needed value at ctreation time use NULL, or any magic number to fill between know values. ie.

invoke construct, SIZEOF OBJECT, 3, ADDR foo, NULL, ADDR bar
if the second parameter is not know at creation time

The code works, but I am concerned that since I'm using TYPEDEF trickery to make invoke take a varilable number of parms, no prolog/epilog is created. Should I clean up the stack?

We got really creative and found a why to do indirect invoke:cool:
But in my test invoke above, you can see I'm using registers. So, again, just for the sake of readability, a linear-array of named DWORDs to store object pointers? I know someone is gonna say STRUC. ie.

foo EA+0
bar EA+4
my EA+8
stupid EA+12
variable EA+16

but not having to use:

(mystruct).foo
(mystruct).bar
(mystruct).my
(mystruct).stupid
(mystruct).variable

I have not looked in this yet. If someone knows a good method.
Thanks.
Posted on 2002-04-20 14:26:06 by ThoughtCriminal
Well, there is the C calling convention?
Posted on 2002-04-20 14:37:35 by bitRAKE
Gee well isn't that a surprise. Bitrake metions C calling convention, so I figure I need to fix the stack.(BTW I don't know what the C calling convention is)

So i write code to fix the stack and *CRASH*. A little debugging later, and it seems I really should not try to fix the stack. The stack is fine when the function returns.
Posted on 2002-04-21 07:24:19 by ThoughtCriminal
Offtopic:
Why don't you have a PM button, ThoughtCriminal?? :confused:
Posted on 2002-04-21 08:53:37 by bazik
IfFieldsEmpty proc C uses ebx edi pcount:DWORD,hndls:VARARG

LOCAL buffer[4]:BYTE
mov edi,pcount
dec edi
@@: invoke GetWindowText,dword ptr hndls[edi*4],addr buffer,4
test eax,eax
je @r
dec edi
jns @B
@r: ret
IfFieldsEmpty endp
Here is an example of a C PROC that can take several parameters on the stack and correct the stack after the invoke automatically.
construct PROC [b]C[/b] oSize:DWORD,pCount:DWORD,parms:[b]VARARG[/b]

invoke GetProcessHeap
invoke HeapAlloc, eax, NULL, oSize
mov ecx, pCount
jmp _2
_1: mov edx,[parms][ecx*4]
mov [eax][ecx*4],edx
_2: dec ecx
jns _1
ret
construct ENDP
I haven't tested this, but it looks like it'd work? :tongue: It copies the parameters last --> first. Also EAX isn't changed so pointer to object is returned.
Posted on 2002-04-21 10:36:21 by bitRAKE
Bazik, I just turned my PM button on. Didn't know I could even have one.

Bitrake, thanks.
Posted on 2002-04-21 11:51:06 by ThoughtCriminal