News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Re: OPTION PROLOGUE:NONE not working

Started by Ratch, April 27, 2006, 02:56:48 AM

Previous topic - Next topic

lingo

Take it easy Hutch,

I like the violins playing too but
I don't afraid to die at the stakes as a heretic...  :lol


Ratch

Greg,

QuoteI prefer using PROC / ENDP, thank you very much.

    Your are welcome.  No one is forced to use any MASM method within the privacy of their own computer.

QuoteThat goes for the other high-level directives too.

    Certainly!

QuoteI don't think anything substantial is gained by not using them.

    I guess you missed the reason stated earlier, that parameters can sometimes be pushed on the stack earlier when they might be available, instead of having store the parameters and let the PROC do it when it is time to call the subroutine.  And don't forget the amount of time and bandwidth expended explaining to nubes why PROCs don't work the way they think they should.  A simple search on PROCs within this forum will confirm that statement.  Also, with cascaded calls to subroutines, do PROCs allow the called subroutine to use the parameters of the previous subroutines, or does one have to PUSH those parameters again on the stack for the called PROC to use? And last but not least, PROCs use up a precious register (EBP) of a already register starved CPU, which has be to saved and restored if used.

QuoteThey are a convenience. If you don't want to use them, knock yourself out.

    An unneeded crutch in my humble opinion.  I get along just fine without them, without knocking myself out.  The STRUCT directive keeps track of the relative positions of the parameters of the dynamic stackframe.  Ratch


   

Ratch

lingo,
QuoteWhy you hold unorthodox opinions in conflict with the dogma of the "Hutch's Assembly Flat Earth Society"?   

     Don't ask me, ask Christopher Columbus.

QuoteImmediately go and delete your "unreadable and unreliable code" and start to learn  how to write "in assembly" in orthodox way...

     Where is it written in stone about what is the "orthodox way"?  Just because Uncle Bill bestowed PROCs to you does not mean you have to use them.

QuoteYou can start to learn with "general purpose" masterpiece or (chef d'œuvre) here:
http://www.masm32.com/board/index.php?topic=6307.0

especially pay attention to:
   dec edx
   dec ecx
@@:
   add edx,1 

     I cannot for the life of me ascertain what is masterful about that code, or what that link is supposed to illustrate.  Perhaps you can elucidate.  Ratch

GregL

If someone wants to get good at programming with MASM, they should learn how to program without using the high-level directives. After you learn that, unless you really need to optimize some code, there is no reason to not take advantage of the high-level directives. 

If you don't want to use them, fine, don't use them. But don't belittle others for doing so. It doesn't make your code superior, in fact, it could be argued that it does the opposite.




Ratch

Greg,

QuoteIf someone wants to get good at programming with MASM, they should learn how to program without using the high-level directives.

     What is a high level directive?  High level with respect to what?  Is PROC/ENDP high level?  If so, why?  I never said that one should not use "high level" directives.  I only stated that I, repeat I, did not find PROC/ENDP helpful.  Other directives like MACRO are about as "high" as you can get, and you never saw me write anything against them in general.

QuoteIf you don't want to use them, fine, don't use them. But don't belittle others for doing so. It doesn't make your code superior, in fact, it could be argued that it does the opposite.

     A recommendation of using a particular method does not belittle anyone not using that method.  It calls attention to a new way of doing things that others can either accept or reject.  I challenge you to find any past posts where I said someone was wrong for not using my method.  If I aver my method to be superior, then I give reasons why it is, and you can challenge those reasons.  Otherwise, you are mischaracterizing what I am doing.  Ratch

hutch--

 :bg

> I don't afraid to die at the stakes as a heretic...

We only light the fire if anyone wants to preach in the Campus, the rest of the place is well geared for heresy.  :P

Ratch,

Having heard most of this stuff before, answer this question for us as in the topic about the MASM operator "OPTION PROLOGUE".

With code like,


; -------------------------------------------------------------------------

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

MyProc proc arg1:DWORD

    mov ecx, [esp+4]
  ; write asm code here
    retn 4

MyProc endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef



What is the difference in terms of code generation in MASM with the following code ?


; -------------------------------------------------------------------------

MyProc:

    mov ecx, [esp+4]
  ; write asm code here
    retn 4

; -------------------------------------------------------------------------


I will save you the trouble of answering, it  is NOTHING. What you need to do is learn enough MASM to know how the OPTION PROLOGUE operator works.

Why bother to use the OPTION PROLOGUE style of code ?

The answer to this one is simple as well, it allows a prototype to be written so the use can use the standard invoke syntax.

All of the older programmers know how to write stack frame free procedures in pure mnemonics so its not as if its a big deal to be able to do so, there are a reasonable number of deviations that are more or less well known for passing values to a procedure, globals, stack frame, arrays, structures, arrays of structures etc etc etc .....
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

sinsi

Quote from: Ratch on March 29, 2007, 02:09:23 AM
...that parameters can sometimes be pushed on the stack earlier when they might be available, instead of having store the parameters and let the PROC do it when it is time to call the subroutine.
That's why I use PUSH/CALL a lot, rather than INVOKE (I push all my WNDCLASSEX stuff onto the stack for RegisterClassEx) - makes more sense to me.

As for the OPTION PROLOGUE thing, surely it only applies if you use PROC/ENDP and not myproc:
Light travels faster than sound, that's why some people seem bright until you hear them.

Ratch

hutch--
QuoteWhy bother to use the OPTION PROLOGUE style of code ?

    So that when you use PROC/ENDP, you do not get all the setup code at the beginning of the subroutine.  I don't use PROC/ENDP, so I don't use OPTION PROLOGUE either.  Just more red tape as far as I am concerned.

QuoteThe answer to this one is simple as well, it allows a prototype to be written so the use can use the standard invoke syntax.

    PROC/ENDP, OPTION PROLOGUE and OPTION EPILOGUE are not needed for PROTO and INVOKE.  I use the INVOKE syntax, and sometimes my own invoke macro INV0KIT within the same file, and they both work fine without PROC/ENDP, OPTION PROLOGUE and OPTION EPILOGUE .  

QuoteAll of the older programmers know how to write stack frame free procedures in pure mnemonics so its not as if its a big deal to be able to do so, there are a reasonable number of deviations that are more or less well known for passing values to a procedure, globals, stack frame, arrays, structures, arrays of structures etc etc etc .....

    The methods are only limited by one's imagination.  Ratch
   

Ratch

sinsi,

QuoteThat's why I use PUSH/CALL a lot, rather than INVOKE (I push all my WNDCLASSEX stuff onto the stack for RegisterClassEx) - makes more sense to me.

     I use a roll my own MACRO called INVOKIT which PUSHes parameters onto the stack in reverse order and then CALLs the subroutine.  It is not guided by PROTO, and therefore does not warn me about the number of parameters PUSHed.  I too PUSH the RegisterClassEx parameters onto the stack and then add the to the ESP register to get rid of the parameters after RegisterClassEx has been called.  No need to keep WNDCLASS around taking up space if it is only going to be used once.

QuoteAs for the OPTION PROLOGUE thing, surely it only applies if you use PROC/ENDP and not myproc:

     Right on.  Ratch

hutch--

hmmmm,

> Just more red tape as far as I am concerned.

So the reason for not using PROC/ENDP and OPTION PROLOGUE is not technical but a personal disposition, it can do nother better than direct manual mnemonic coding and is nothing more than a sales pitch for a particular coding technique.

> I too PUSH the RegisterClassEx parameters onto the stack and then add the to the ESP register to get rid of the parameters after RegisterClassEx has been called.

But why would you use such an inefficient technique that does its stack adjustments after each function call rather than doing it in one instruction at the end of the Proc ? The whole purpose of using LOCAL or what are often called automatic variables is so you don't write sloppy code that does them sequentially instead of the efficient way at the end.

One trailing stack adjustment at the end of the proc is far more efficient than adjusting the stack after each function call.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Ratch

hutch--,

QuoteSo the reason for not using PROC/ENDP and OPTION PROLOGUE is not technical but a personal disposition.

     It is partly technical.  See reply #31 of this thread for some technical reasons.  Because of those technical reasons, I like it.

Quoteit can do nother better than direct manual mnemonic coding

     I  think my method is quite direct and more manual.  More so than PROC/ENDP.  Of course direct manual coding can do anything.  It is just a question of coding difficulity and resource tradeoffs. 

Quoteand is nothing more than a sales pitch for a particular coding technique.

     Nothing to sell, nothing to buy, no profit involved.  Just a good faith advocacy of a method I think is better, at least for me.  Everyone has to decide for themselves if the method is for them.

QuoteBut why would you use such an inefficient technique that does its stack adjustments after each function call rather than doing it in one instruction at the end of the Proc ? The whole purpose of using LOCAL or what are often called automatic variables is so you don't write sloppy code that does them sequentially instead of the efficient way at the end.

     1) That particular API, RegisterClass, is usually called only once in a program, so it does not have to be top efficient.
     2)  It does not leave dead storage (WNDCLASS) lying around in memory for the life of the program.
     3)  I don't have to PUSH the parameters sequentially for WNDCLASS.  I can write them to the stack directly and out of order using the WNDCLASS structure.
     4)  RET XXX does the same thing as (ADD ESP,XXX) , albeit slightly more efficiently.  Not enough to matter though. 

Ratch

hutch--

 :bg

>  It is partly technical.

It either is or it ain't and I sugest that if you understand how the OPTION PROLOGUE operators work in relation to PROC / ENDP you would not make these claims.

>  I  think my method is quite direct and more manual.  More so than PROC/ENDP.

Same problem of you not understanding the OPTION PROLOGUE operators in MASM.

> Nothing to sell, nothing to buy, no profit involved.  Just a good faith advocacy of a method I think is better, at least for me.

A sales pitch by any other name is still a sales pitch and it is for a technique that cannot do anything that the PROC / ENDP operators cannot do using the OPTION PROLOGUE operator.

Quote
     1) That particular API, RegisterClass, is usually called only once in a program, so it does not have to be top efficient.
     2)  It does not leave dead storage (WNDCLASS) lying around in memory for the life of the program.
     3)  I don't have to PUSH the parameters sequentially for WNDCLASS.  I can write them to the stack directly and out of order using the WNDCLASS structure.
     4)  RET XXX does the same thing as (ADD ESP,XXX) , albeit slightly more efficiently.  Not enough to matter though. 

1) So lousy code is justified if you only use it once no matter how inefficient it is.
2) The stack is already pre-allocated, dead storage in this context is nonsense.
3) You are confusing your own view of allocating from the stack and freeing it after the function call with pushing arguments in sequence. Your method of allocating from the stack then deallocating it directly after the function call is SEQUENTIAL where the normal method of writing to local or automatic variables is far more efficient and only requires the stack to be balanced at the end of the PROC.
4) "RET XXX does the same thing as (ADD ESP,XXX)" This is nonsense, a RET(N) branches back to the following instruction after the CALL and if it uses the trailing WORD size number it corrects the stack as well. Adding to the stack pointer only corrects the stack.

RET and CALL are balanced opcodes on any of the later processors so using any technique that interferes with this balance is again very inefficient coding practice.

It seems that you are willing to throw away many more efficient programming techniques on the alter of flogging a method that by your own admission is inefficient when the normal PROC / ENDP suffers none of the problems that your own method does. Freestyle architecture goes towards full manual mnemonic coding, not pre-canned methods that have a number of buit in inefficiencies contained within its design.

Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Ratch

hutch--,
     
QuoteIt either is or it ain't and I sugest that if you understand how the OPTION PROLOGUE operators work in relation to PROC / ENDP you would not make these claims.

     Not everything in this world is on/off, black/white.  When I said that my reasons for not using PROC/ENDP were partly technical, that is what I meant.  No arguments  you countered with prove otherwise.  My dislike for PROC/ENDP is technical for reasons already given, and personal for the extra red tape they cause.  Combine the two, and you get partial technical and partial personal. 

QuoteSame problem of you not understanding the OPTION PROLOGUE operators in MASM.

     Wrong, not much to understand.  It either adds or suppresses beginning/prolog code, which I don't need.

QuoteA sales pitch by any other name is still a sales pitch and it is for a technique that cannot do anything that the PROC / ENDP operators cannot do using the OPTION PROLOGUE operator.

     It is a pitch, but not a sales pitch.  Don't you see the distinction?  And are you not "pitching" the PROC/ENDP directives which cannot do some things my method can do, and is less flexible for the reasons given earlier.

Quote1) So lousy code is justified if you only use it once no matter how inefficient it is.

     You have to prove that it is lousy code.  So far you have not done that.  Why would it be lousy code to put the parameters for RegisterClass on the stack instead of a .DATA or .DATA? segment?  All CALLs to APIs do that.

Quote2)  It does not leave dead storage (WNDCLASS) lying around in memory for the life of the program.

     It does if you put the parameters in a .DATA(?) segment.  Unless you reuse the WNDCLASS storage for something else.

Quote3) You are confusing your own view of allocating from the stack and freeing it after the function call with pushing arguments in sequence. Your method of allocating from the stack then deallocating it directly after the function call is SEQUENTIAL where the normal method of writing to local or automatic variables is far more efficient and only requires the stack to be balanced at the end of the PROC.

     Nothing wrong with being sequential.  The "normal" method of reading/writing to a PROC/ENDP stackframe is to use an offset with respect to EBP, whereas my method uses ESP.  Are you saying that EBP is far better or far faster?  At the expense of using the EBP register?  And one has to save/restore EBP and balance the stack at the end, too.  I think you should explain what you mean a little better.

Quote4) "RET XXX does the same thing as (ADD ESP,XXX)" This is nonsense, a RET(N) branches back to the following instruction after the CALL and if it uses the trailing WORD size number it corrects the stack as well. Adding to the stack pointer only corrects the stack.

RET and CALL are balanced opcodes on any of the later processors so using any technique that interferes with this balance is again very inefficient coding practice.

     Of course I know that RET XXX returns back to where it was called after balancing the stack.  I would not be able to do what I do unless I did know that.   What I should have made clearer is that RET XXX does an effective (ADD ESP,XXX) before it returns.   My method does a call/ret XXX sequence, so no problem with balancing the call/ret sequence either.

QuoteIt seems that you are willing to throw away many more efficient programming techniques on the alter of flogging a method that by your own admission is inefficient when the normal PROC / ENDP suffers none of the problems that your own method does. Freestyle architecture goes towards full manual mnemonic coding, not pre-canned methods that have a number of buit in inefficiencies contained within its design.

     Not at all.  I never said my code was inefficient. You did.  I believe my method is more efficient because it uses fewer resources (no EBP usage and overhead), and is more flexible, especially in cascaded calls.  Why don't we compare a simple coding by your method and my method?  Ratch

hutch--

 :bg

> Not everything in this world is on/off, black/white.

The truth of a statement is, its called the "Law of excluded middle".

> When I said that my reasons for not using PROC/ENDP were partly technical, that is what I meant.

Not in the context of the topic, the use of OPTION PROLOGUE renders your arguments nonsense. You may have a dispositional problem with the standard MASM notation but using OPTION PROLOGUE/EPILOGUE to turn off the generation of a stack frame makes ALL of your arguments nonsense. The PROC / ENDP then serve a different purpose, that of being the MASM defined model of the procedure that is matched with a prototype for the procedure.

You may whinge about the extra "red tape" but it is THE MASM defined method of writing a stack frame free procedure that still has a working standard MASM prototype. To make the point again, there is NO DIFFERENCE in the code generation between a fully manually coded procedure and the code that is generated between the OPTION PROLOGUE/EPILOGUE operators but the standard MASM method of creating a prototype works as it was designed to work.

> And are you not "pitching" the PROC/ENDP directives which cannot do some things my method can do, and is less flexible for the reasons given earlier.

I am "pitching" the standard MASM method of using PROC / ENDP either with OR without the OPTION PROLOGUE/EPILOGUE operators depending on what you require. One generates a standard MASM stack frame procedure, the other generates EXACTLY what you write between the operators but with the added advantage that it allows a standard MASM prototype and collectively this pair of techniques are exhaustive. Your claim that there is a technical reason NOT to use PROC / ENDP in conjunction with the OPTION PROLOGUE/EPILOGUE operators is simply nonsense, you can code ABSOLUTELY anything between them.

Now when it comes to coding efficiency with one of the techniques you have described, either pushing the arguments for a WNDCLASSEX structure directly onto the stack or manually allocating space on the stack then writing the arguments to the stack and, calling the stack address with RegisterClassEx() and then correcting the stack after the function has returned, I will make the same criticism that your code is sloppy and inefficient in comparison to a normal LOCAL structure which is preallocated at the beginning or the procedure and cleaned up at the end as the standard LOCAL is simply more efficient as it does less work than you repeated stack corrections.

I have occasionally used this technique when I had a stack frame free procedure as a matter of convenience but it is certainly less efficient than a LOCAL variable.

I have no doubt that the method you use works but you are the one who has repeatedly tried to inflict it on others on the basis of it being in some sense "better". Technically its is not and is less efficient code.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Ratch

hutch--,

QuoteThe truth of a statement is, its called the "Law of excluded middle".

     The truth in this case is fuzzy logic, in which statements may be true, false, or somewhere in between.  In rhetoric, the law of excluded middle is readily misapplied, leading to the logical fallacy of the excluded middle, also known as a false dilemma.

QuoteNot in the context of the topic, the use of OPTION PROLOGUE renders your arguments nonsense.

     In what way?  Why do I need it for my method?

QuoteYou may have a dispositional problem with the standard MASM notation but using OPTION PROLOGUE/EPILOGUE to turn off the generation of a stack frame makes ALL of your arguments nonsense. The PROC / ENDP then serve a different purpose, that of being the MASM defined model of the procedure that is matched with a prototype for the procedure.

     Ah!  Now I determined what you are saying.  I always thought that PROTO would work without PROC/ENDP, but I just tried it and it does not.  Strange, I have never explicitly coded PROTO in my code before.  In fact, I developed a MACRO called INVOKIT to bypass parameter counting.  That was so I could PUSH parameters before the INVOKE.  I guess I never missed the benefits of PROTO too much because oftentimes I bypassed it.

QuoteYou may whinge about the extra "red tape" but it is THE MASM defined method of writing a stack frame free procedure that still has a working standard MASM prototype. To make the point again, there is NO DIFFERENCE in the code generation between a fully manually coded procedure and the code that is generated between the OPTION PROLOGUE/EPILOGUE operators but the standard MASM method of creating a prototype works as it was designed to work.

     Personally I don't plan to use the PROC/ENDP method, but I can see how someone who wants MASM to count the INVOKE parameters would.  However, my method is not about counting parameters, it is about managing the stack manually and not using the EBP register.

QuoteI am "pitching" the standard MASM method of using PROC / ENDP either with OR without the OPTION PROLOGUE/EPILOGUE operators depending on what you require. One generates a standard MASM stack frame procedure, the other generates EXACTLY what you write between the operators but with the added advantage that it allows a standard MASM prototype and collectively this pair of techniques are exhaustive. Your claim that there is a technical reason NOT to use PROC / ENDP in conjunction with the OPTION PROLOGUE/EPILOGUE operators is simply nonsense, you can code ABSOLUTELY anything between them.

     What you say is true, it is exhaustive but verbose.  Its "features" I don't need and I often bypass.

QuoteNow when it comes to coding efficiency with one of the techniques you have described, either pushing the arguments for a WNDCLASSEX structure directly onto the stack or manually allocating space on the stack then writing the arguments to the stack and, calling the stack address with RegisterClassEx() and then correcting the stack after the function has returned, I will make the same criticism that your code is sloppy and inefficient in comparison to a normal LOCAL structure which is preallocated at the beginning or the procedure and cleaned up at the end as the standard LOCAL is simply more efficient as it does less work than you repeated stack corrections.


     I don't know how you can say that.  Pushing parameters has to be the most efficient way of putting something on the stack.  After the CALL, one stack correction finishes up.  What's sloppy about that?  A LOCAL structure has to preallocate the stack, then write with either the ESP or EBP offset, and finally correct the stack after the CALL.  How is writing to the stack with ESP or EBP more efficient than a PUSH?

QuoteI have no doubt that the method you use works but you are the one who has repeatedly tried to inflict it on others on the basis of it being in some sense "better". Technically its is not and is less efficient code.

     I assume you are talking about putting WNDCLASS on the stack.  You should explain how a PUSH is less efficient than a direct write to the stack.  Ratch