The MASM Forum

General => The Campus => Topic started by: Grincheux on January 07, 2016, 03:47:07 AM

Title: PROLOGUE YES or NO
Post by: Grincheux on January 07, 2016, 03:47:07 AM
When I use the PROLOGUE option that makes easy to make calls, create local varibles...
When I read Jochen sources he does not use the prologue?
Why?
What is the best choice?
Title: Re: PROLOGUE YES or NO
Post by: dedndave on January 07, 2016, 06:02:58 AM
it's simply a matter of knowing what the assembler generates for automatic prologue and epilogue
once you understand what it does, you can make the choice that best suits the function

when speed is an issue (the function is called thousands of times, perhaps),
it may be best to write your own prologue and epilogue

otherwise, using the assembler automatic prologue and epilogue makes for more readable code
Title: Re: PROLOGUE YES or NO
Post by: Vortex on January 07, 2016, 06:35:38 AM
Hi Grincheux,

As Dave said, it's a matter of personal choice. You can remove the prologue \ epilogue sections for optimization purposes.
Title: Re: PROLOGUE YES or NO
Post by: jj2007 on January 07, 2016, 06:38:11 AM
Quote from: Grincheux on January 07, 2016, 03:47:07 AMWhen I read Jochen sources he does not use the prologue?

90% of my procs do have a prologue. But occasionally you can produce shorter and/or faster code without, mainly if
- you have enough spare registers (i.e. no need for locals)
- you need to access the arguments only a few times

If you access args frequently, code size will be shorter with a stack frame:
mov eax, [ebp+nn] is one byte shorter than
mov eax, [esp+nn]
Title: Re: PROLOGUE YES or NO
Post by: Grincheux on January 07, 2016, 07:03:30 AM
Thank you every one it is clear. I have been very pleased to get your help all the time I was programming this utility.

For Jochen : In my program CatchWebImages (http://www.phrio.biz/mediawiki/Catch_Web_Pages) I have used two functions MbStrLen and InstrJJ.

If you write an InstrJJ backward function think to me.
Title: Re: PROLOGUE YES or NO
Post by: jj2007 on January 07, 2016, 08:10:10 AM
Quote from: Grincheux on January 07, 2016, 07:03:30 AMIf you write an InstrJJ backward function think to me.

There is Rinstr() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1154), but it's not particularly fast:

Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz (SSE4)
34076   cycles for 100 * InString
26291   cycles for 100 * MB Instr_()
7121    cycles for 100 * MB Instr_(FAST, )
29626   cycles for 100 * MB Rinstr()
31901   cycles for 100 * CRT strstr
Title: Re: PROLOGUE YES or NO
Post by: ragdog on January 07, 2016, 08:54:32 AM
To PROLOGUE option
http://www.masmforum.com/board/index.php?PHPSESSID=786dd40408172108b65a5a36b09c88c0&topic=11514.0

But i have never used if i use Global and local Variables have i problems to calc the esp pointer ::)
And a good tutorial about it have i never found.
Title: Re: PROLOGUE YES or NO
Post by: dedndave on January 07, 2016, 11:05:06 PM
http://masm32.com/board/index.php?topic=3326.msg35046#msg35046 (http://masm32.com/board/index.php?topic=3326.msg35046#msg35046)

http://masm32.com/board/index.php?topic=3326.msg35052#msg35052 (http://masm32.com/board/index.php?topic=3326.msg35052#msg35052)
Title: Re: PROLOGUE YES or NO
Post by: hutch-- on January 08, 2016, 04:51:15 AM
Philippe,

> If you write an InstrJJ backward function think to me.

They are not that hard to write, once you have the word length to find, subtract that from the text length then scan backwards testing each start character and following characters to see if you get a match. Stop when the 1st search character is the start of the text being searched. return whatever return value you want on match or no match, I usually use 0 for no match or the offset from the front for a match.

RE: The PROLOGUE and EPILOGUE notation, it is mainly used to turn the automatic stack frame off so if you are writing a leaf procedure (one that does not call other procedures) you reduce the stack overhead by writing it with no stack frame. You can do it even faster by using a register to pass the values, its a roll your own version of FASTCALL where you can pass data in EAX, ECX and EDX and return up to 3 values in the same three registers.
Title: Re: PROLOGUE YES or NO
Post by: Adamanteus on January 08, 2016, 05:29:08 AM
My real code, that solving this problem looks, like this :
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

strlen  PROC FUNC_IMP_ASM, ; USES preserve,
string : POINTER
ifdef HUTCHSTRLEN
ifidni FUNC_IMP_ASM, <FASTCALL>
    mov     eax, ecx           ; get pointer to string
else
    mov     eax, [esp + 4]           ; get pointer to string
endif
...


But problem is really conceptual, as best way to strip when no need prologue and epilogue, that's automatically by assembler, but that is to JWasm authors request ...
Title: Re: PROLOGUE YES or NO
Post by: Grincheux on January 08, 2016, 06:06:04 AM
First : Reply to Hutch.

I have wrote my own but Jochen code is very efficient, for this reason I told him to think to me.
You are right for passing the parameters, I continue using standard prologue and epilogue, but if I can write a function which takes its parameters throught the registers, I define the function as a label.

Adamanteus, you are a fox. It's a good idea.
Title: Re: PROLOGUE YES or NO
Post by: hutch-- on January 09, 2016, 02:17:15 AM
Philippe,

Here is a small demo of FASTCALL versus inlined code The second is faster again than a FASTCALL. The algo is a tiny and not that fast byte scanner for a string length but it is trivial, it only demos the technique difference.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

; *****************************

    lost MACRO                      ; length of string
        mov ecx, eax
        sub eax, 1
      lbl:
        add eax, 1
        cmp BYTE PTR [eax], 0
        jne lbl
        sub eax, ecx
    ENDM

; *****************************

    .data
      item db "12345678901234567890",0

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    mov eax, OFFSET item
    call sln                ; call procedure
    print str$(eax),13,10

    mov eax, OFFSET item
    lost                    ; run inline macro
    print str$(eax),13,10

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

sln proc

    mov ecx, eax

    sub eax, 1
  lbl:
    add eax, 1
    cmp BYTE PTR [eax], 0
    jne lbl

    sub eax, ecx

    ret

sln endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
Title: Re: PROLOGUE YES or NO
Post by: Grincheux on January 09, 2016, 02:26:33 AM
Thank you Hutch

The difference is the time for calling the proc.

I would like to answer you if rather having many local variables we define a structure for accessing these variable, is it good ?
An other thing, if I do a PUSHF, what becomes the flags affected by instructions before I do the POPF?
Would it be better to do :

PUSHF
Instruction 1
Instruction 2
POPF

OR

PUSHF
Instruction 1
.
.
.
Instruction <n>
POPF

When I was programming under MSDOS with the famous INT 21h, the STC instruction was called to signal an error. Why this his not the same now on Windows?

I don't speak to you very often, but now I made it for a year!
Title: Re: PROLOGUE YES or NO
Post by: hutch-- on January 09, 2016, 03:21:18 AM
Here is a better version with simple timing.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

; *****************************

    lost MACRO                      ; length of string
    LOCAL lbl
        mov ecx, eax
        sub eax, 1
      lbl:
        add eax, 1
        cmp BYTE PTR [eax], 0
        jne lbl
        sub eax, ecx
    ENDM

; *****************************

    .data
      item db "12345678901234567890",0

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL tc    :DWORD

    push ebx
    push esi
    push edi

    mov eax, OFFSET item
    call sln                ; call procedure
    print str$(eax)," correct test",13,10

    mov eax, OFFSET item
    lost                    ; run inline macro
    print str$(eax)," correct test",13,10

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

    mov esi, 100000000

    fn GetTickCount
    push eax

  lbl1:
    mov eax, OFFSET item
    call sln                ; call procedure
    ; print str$(eax),13,10
    sub esi, 1
    jnz lbl1

    fn GetTickCount
    pop ecx
    sub eax, ecx

    print str$(eax)," ms FASTPROC",13,10

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

    mov esi, 100000000

    fn GetTickCount
    push eax

  lbl2:
    mov eax, OFFSET item
    lost
    ; print str$(eax),13,10
    sub esi, 1
    jnz lbl2

    fn GetTickCount
    pop ecx
    sub eax, ecx

    print str$(eax)," ms INLINE CODE",13,10

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

    pop edi
    pop esi
    pop ebx

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

sln proc

    mov ecx, eax
    sub eax, 1
  lbl:
    add eax, 1
    cmp BYTE PTR [eax], 0
    jne lbl
    sub eax, ecx
    ret

sln endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
Title: Re: PROLOGUE YES or NO
Post by: hutch-- on January 09, 2016, 03:23:55 AM
Using a structure is a tidy and convenient technique but its still memory operands which are slower than registers. On a longer procedure its fine but on very short procedures you are just adding extra memory operands which slow it down.
Title: Re: PROLOGUE YES or NO
Post by: hutch-- on January 09, 2016, 04:06:18 AM
There is yet another technique from the Win3 16 bit days when you had very little stack space. Allocate a set of GLOBAL variables of the right size and pass values in the globals. Again it can only be used safely with leaf procedures but it lives somewhere between the speed of inlined code and a no stack frame procedure.
Title: Re: PROLOGUE YES or NO
Post by: jj2007 on January 09, 2016, 04:41:53 AM
Quote from: hutch-- on January 09, 2016, 04:06:18 AMpass values in the globals. Again it can only be used safely with leaf procedures

Why unsafe?

I use a hybrid: SetGlobals (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1015) uses the LOCAL somevar:DWORD syntax, but mov eax, somevar is mov eax, [ebx+n] under the hood, where n is -128...+128 (and more). Speed-wise as fast as global variables, but shorter encoding.
Title: Re: PROLOGUE YES or NO
Post by: Grincheux on January 09, 2016, 06:04:26 AM
You make your heap manager
Title: Re: PROLOGUE YES or NO
Post by: hutch-- on January 10, 2016, 12:25:12 PM
 :biggrin:

Well, there is safe and there is SAFE, try a recursive quick sort that iterated hundreds of thousands of calls deep and you will understand why fixed globals are not the solution. You can have many more fixed globals than registers and they are slightly slower than true FASTCALL but not by much.
Title: Re: PROLOGUE YES or NO
Post by: Grincheux on January 10, 2016, 02:09:18 PM
I am OK with you Hutch. It is like trying to program a recursive application in FORTRAN.