Subj as it appiears is 32 params.
If more - you get message:
"Statement is too complex" :)
:(
Not good for many C like functions.
Posted on 2002-03-17 09:23:10 by The Svin
An easy workaround would be, to create a STRUCTure with alle the >32 parameters and just pass the address of the structure to the function.

Hope this helps! :alright:

bAZiK
Posted on 2002-03-17 09:53:54 by bazik
Hi!

Use "PUSH" for all the other params!

Push 37
Push 36
Push 35
Push 34
Push 33
Invoke YeahBabyYeahA,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32

Be sure that your stack wont overflow :)
Posted on 2002-03-17 10:02:51 by Rennsemmel
Thanx guys for your creative ideas ;)
They are quite obvious, you know :)
But all sence of invoke in C like procs is to culculate stack
correction after all, not just ability to write params in line
with comma delimiter.
to bAZiK:
so what? you passed address of the struct to szMultiCat for example, and what will happened?
the function will think that there are for example 42 adresses of strings pushed in the stack while actually there are just one.
Forget it :)
There are lots of usefull C like function with variable number of
params, and 32 is nothing but too little for possible serious task.
Invoke inner macros is just not done well.
Posted on 2002-03-17 10:17:56 by The Svin
Svin, obviously another limitation of MASM - I wasn't aware of this one. :( Might want to try rewriting the PROLOGUE/EPILOGUE macros yourself before writing your own assembler. :)
Posted on 2002-03-17 11:35:39 by bitRAKE
That's actually quite smart, as a proc that needs you to push > 32 params wouldn't be very practical. You're better off passing it as a reference to a param structure.
Posted on 2002-03-17 11:53:00 by iblis
iblis, that doesn't aply to the C calling method - you can write some good code that leaves the parameters on the stack for multiple processing by several PROCs with the same (or less) parameters - this would be efficent in many situations. I never really liked STDCALL. :)
Posted on 2002-03-17 12:02:58 by bitRAKE
To adjust for STDCALL all you'd need to do is readjust the stack pointer when the proc returned, no? (assuming the called proc didn't destroy the params)

BTW I've never seen a program that needed to push > 32 arguments on the stack. I'd be interested to see one where it is more beneficial to push all 32 args then to just pass it as a struct reference. Any examples out there?
Posted on 2002-03-17 13:26:05 by iblis

That's actually quite smart, as a proc that needs you to push > 32 params wouldn't be very practical. You're better off passing it as a reference to a param structure.


In opposite it is quite stupit and limited.
Do you care carefully read post before answering?
We are talking of C like functions e.i. functions with variable number of params.
What structure you're talking about?
For example you need in one line cat 52 strings in one and in another 37.
What would you do? Write "personal" structure for every line?
You need validate 27 fields in one form and do in another form it with 44 fields, what you do? Write personal proc for each form?

People you need start to write some big apps with huge data input output processing. We just talking different languages.
Posted on 2002-03-17 13:42:54 by The Svin
Originally posted by The Svin In opposite it is quite stupit and limited. Do you care carefully read post before answering?
We are talking of C like functions e.i. functions with variable number of params.


I didn't realize you were speaking of varargs. "C like functions" is kind of vague and I missed your 2nd post.

Originally posted by The Svin What structure you're talking about?
For example you need in one line cat 52 strings in one and in another 37.
What would you do? Write "personal" structure for every line?
You need validate 27 fields in one form and do in another form it with 44 fields, what you do? Write personal proc for each form?



No I'd probably just loop through each field in the form, validating each one as I go. When I reach an invalid field, or # of iterations = myForm->numberOfFields, I stop validating.

Pseudo-code:
bool FORM::IsValid( void )

{
for( int i = 0; i < this->numberOfFields; i++ )
{
switch( this->field[i].type )
{
case EMAIL:
break;

case ALPHAONLY:
break;

case NUMERICONLY:
break;

etc.. etc..
}
}
}
Posted on 2002-03-17 15:42:31 by iblis



In opposite it is quite stupit and limited.
Do you care carefully read post before answering?
We are talking of C like functions e.i. functions with variable number of params.
What structure you're talking about?
For example you need in one line cat 52 strings in one and in another 37.
What would you do? Write "personal" structure for every line?
You need validate 27 fields in one form and do in another form it with 44 fields, what you do? Write personal proc for each form?

People you need start to write some big apps with huge data input output processing. We just talking different languages.


linked lists? I agree that it's better to push a 'dynamic structure' such as an array, instead of pushing multiple single parameters if the number of parameters required exceeds a certain limit.
Posted on 2002-03-17 18:08:09 by Hiroshimator
What do you want? Singly - Singly Circular - Doubly - Doubly Circular? we all have 'em here :)
Posted on 2002-03-17 18:10:48 by stryker
A method also used in WinAPI, is to create a structure where its first member will be the number of valid members. For example, you create a structure of 100 dwords: If you need to pass the addresses of 68 strings, you put 68 in the first member and the called function reads the next 68 pointers. There is no difference in vararg functions, they always get the number of pushed parameters someway.
Posted on 2002-03-17 18:34:43 by micmic
to micmic:
It's OK when you know num of params in desing time and yet
it is not better way, creating additional stack like memory locations when you already have the stack and can do it all there.
to all:
Everything you preposed is a slappy way out
from a problem wich was created not by natural
cause but by bad realisation of inner macro in MASM.
I'd rather calculate manually stack adjustment than
waste a lot more time to create a bigger and slower
code using dynamically allocated strucs where it
is not appropiate.

And don't give me here in asm board C code - it kinda
hurts my eyes for numerous reasons:
1. C compilers don't have the same problem with
stack adjusments and number of params. You can call
wsprintf there and don't bother if number of params bigger
the 32.
2. I use C like convention when it
- create faster code
- lead to smaller code in project
- save my time for typing.
All it's clear when you consider LOW LEVEL anvantages
and from C code you can not see this LOW LEVEL things
3. From the C code the above I can see only preposition to
write 10s time a day similar code instead of writing it once
and forever.

Cause I see that most of people here unfamiliar with huge
data prosessing along with writing database enjeens I give
some more understandable:

Imagine that by nature of your work you need several times
a day write code wich cat rapidly located strings in one for
output, each time number of those strings is different.
Speed is matter. I've been hired as asm programmer to
write
1. Fast code - so you can not go away with just a solution -
you need fast solutions (to make code for example wich
currently run 15 secs run 2 secs)
2. You need write a lot of code every day and solve a lot
of problems so time spent to write code is matter for you too.

You'd eventually end up with some proc like szMultiCat or
more optimized version of it.
It doesn't need any structs, it uses universal place as temp
buffer - stack, it frees you from annoing job creating loops
each time you need cat strings, and in addition - you need
just call it passing params so it saves place for you don't
need write code loops each time you need cat some more
strings again.
Now show me how you do it with struct approach so that
it would be easier than that, faster, less code writing consuming,
and results in smaller code and easier for programmer to handle
code.

People, I know I might sound rude, but sometimes especially
when it comes to discussion of speed advantages writing
in asm the discussion is going to nowhere for simple reason:
there are very few progs written in asm that carries huge tasks
that needed speed.
Except for games and graphic programmers of course, you don't
need to talk them in importance of optimised code, they know it
well themselves.
But there are 1000s tasks that waits for fast progs.
Most of them still made better in command processors then in
3d party programms.
I can name a lot of those problems (small and big) that or don't solved at all or
in current realisations work slow even on current machines.
Actually I don't see any noticebale speeding up from user point of view brought with huge advance of hardware. While hardware enjeneers did there work very impressive software developers constantly killing possibility given by hardware with there slappy programming. 99% software developers take this advance of hardware not as appeal to take part in making the world better but as excuse to write worse than even in the past code justifying iit that "hardware is so fast now so there is no need to write carefull code". From logical point of view it means that in hardware we can see progress and in software - regress and result of those
to processes is ZERO. Faster run is only with OLD apps. New ones just spoiled hardware results equally to improvement of it done by hardware developers.


Start write usefull progs that carries tasks needed speed.
Then we start talking the same language.
I saw a little example of such task in algo section - regscan,
make it faster and make a way to put output to some more
convinient place for user than console.
A lot of people will use it and you'd fill taste of problems that
need speed.
Posted on 2002-03-18 03:39:56 by The Svin
Alex,

I don't know if there are limitations on the way you write macros but it may be a way to defeat this limitation. This macro from MASM32 may do the job if there are no other macro limitations. All that you need to do with it is increase the number of parameters it will handle.


; ------------------------------------------------------------------
; macro for making STDCALL procedure and API calls.
; ------------------------------------------------------------------

Scall MACRO name:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12, \
p13,p14,p15,p16,p17,p18,p19,p20,p21,p22

;; ---------------------------------------
;; loop through arguments backwards, push
;; NON blank ones and call the function.
;; ---------------------------------------

FOR arg,<p22,p21,p20,p19,p18,p17,p16,p15,p14,p13,\
p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>
IFNB <arg> ;; If not blank
push arg ;; push parameter
ENDIF
ENDM

call name ;; call the procedure

ENDM

Regards,

hutch@movsd.com
Posted on 2002-03-18 03:46:54 by hutch--
Thanks, Steve, but in C convention the macro also needs to adjust stack after all.
To all:
Actually when I wrote my first post I got solution by macro,
my intention of the post was just warn those who might be interested about the limitation in invoke.
After that I a little bit overreacted reflecting on proposition to
use structs in such cases :)
I hope you'll forgive my reflection ;)
In asm there are 16 ways to call procs and pass params,
and stdcall way is not always the best one.
It's good just cause became universal, but ...
This is my point of previous posts.
Thanks for your attention.
Posted on 2002-03-18 06:35:51 by The Svin
just tried it out. with fixed parameters the limit is 32, with VARARG in proto the limit is 48 params (MASM 6.15)
Posted on 2002-03-18 06:49:01 by japheth
Yes, if there is ONLY VARARG.
Try to put before VARARG couple DWORDs and result will be
the same 32 params limit.
Posted on 2002-03-18 14:11:57 by The Svin
Okay, i have a question.... Svin, feel free to pass on
your wisdom....

For a function that takes a variable number of arguments
(wsprintf, for example), how does the function know how
many arguments it is receiving? I know that this does not
apply to actually cleaning up the stack, as the calling function
does that. Instead this concerns the function popping values
off the stack, how many should it pop before it stops?

With Svin's strcat problem, this is how i see it working:


- call custom strcat function with an arbitrary number of arguments
- empty large buffer we maintain for this function
- enter loop
- pop string pointer off the stack
- copy string to our large buffer
- check if we have any pointers left on stack
- if we have more pointers, do loop again
- (note: how do we know it is a string pointer, and not part of
the stack frame from the calling function?)
- exit loop
- pass pointer to buffer back to user


I know that there is a flaw or two with my passing back of the
pointer to the finalised string, but i am keeping it simple :)
Unless i have totally misunderstood what Svin is wanting to
do, how could there be a quicker method than this?
Posted on 2002-03-18 17:27:45 by sluggy
There are numerous way for called function
to know number of params.
It maybe passed as one of predefined arguments
though the function does not know at the begining
nor address of last arg niether number of them it knows
address of predefined arg (for example after
creating frame it might suppoused to be )
Another way - push special (ending) value as last argument,
and before processing next arg from the stack function
suppose to check if it is ending value - if so - it's done.
wsprintf know if there is any more values processing
template for "%i" ,"%s" .etc strings.
There are a lot more ways to syncronize working
between caller and callee, usually callee doesn't pop
anything - args remains in callculated place as memory
vars. Predefined args (required) go first so their place
could be calculated, varargs - after them.
Simple example of the first described method:
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
Of course there is no problem to write such code each time you need it
- except that it would be just waste of your time and bigger release.
Macros in the case could save your typing time but generate additional
code while using the proc above needs to write it once and forever and
code itself doesn't take additional amount of space. You just use space
to pass params and call it each time you need it, not for code itself.
You can arrange, of course, such task to pass params from struct, but
question is what for? You need additional memory var for it, while you
already have stack, and you doomed to warry if those strucs are large
enough to handle all params. I understand using structs (and I use them
havily) when it is appropriate, so that it might save size or speed up things.
For example if several times pass the same struc addr as place for args,
but fully fill it just for the first time, for next calls you may replace just
few of args in the struct and it will save time cause you don't need
pass(or fill) all params each time. But it is different thing.
In that case there is NATURAL need (reflecting of result - speed) to
do it so your going for struct approach is senceble and reasonable,
not in the case when you force to do it 'cause you main tool fails to
do what you need.
We are the masters - tools are slaves.
Probably almost all here are able looking at ready progs written in HLL IDE
figure out whether it was written on VB, Delphy of VC++.
That is thing I fear most - when your tool reflect on your result, then
the tools became masters.
One of reason I use asm - to have more control.
Of course, my work is still affected by tools, but at least I'm
trying to ask myself - why did I do it - cause it was right way to do or
just cause it was easy to do with the tool I'm currently using?
They SHALL OBEY OUR WISH AND COMMANDS! :)
Otherwise we become kinda slaves :)
Posted on 2002-03-19 01:55:15 by The Svin