It is unclear to me why the author of the book i'm reading uses different methods of procedure entry.

On all entries i can find an "enter" instruction wich i understand more or less but instruction pairs like the following seem to appear almost randomly:
pusha and pushf,
only pusha
or
push ebx push esi even.

I can understand perhaps "pusha and pushf" but the others? They are example procedures not custom made to fit in custom code so i don't undertand.
Posted on 2006-08-01 08:32:07 by w0lfshad3
First things first: accept that your assembler will, unless instructed otherwise, generate either 'enter' and 'leave' opcodes, or alternatively, opcodes which do the same thing (screw with ebp and esp).
Some people call these procedure entry and exit opcodes 'bookends', and other people call them 'prologue and epilogue'. Their job is to set up a 'procedural stackframe', whose purpose is to set aside a region of Stack memory for the Procedure to use (and to 'protect' the input parameters and return address that are ALREADY on the Stack).
There are occasions where we neither want nor need a 'procedural stackframe', but that's not something you'll have to worry about for quite a while.
Now, to your main question:
Those pushes are to preserve the content of particular registers for the duration of the procedure.
For example, imagine you have some procedure which uses the ecx register... but the code which calls that procedure ALSO uses the ecx register, and you want the value in ecx to be 'protected' from being 'trashed' during the procedure... when the procedure returns to the caller, we want the value in ecx to be the same as it was when we made the call...
You would PUSH ECX at the beginning of the procedure, and POP ECX at the end of the procedure.

For your information:
The MASM assembler provides us with another way to preserve one or more registers during a procedure.. we can declare which register(s) we care about in the procedure declaration's first line, via the 'uses' directive:

MyTerribleFunction proc uses esi ebx ecx Param1,Param2,ParamX...
;blah in here
ret
MyTerribleFunction endp

The assembler will actually generate code similar to what you've seen, with all those pushes and pops at the procedure entry and exit.
It will even do so for procedures with more than one exit such as this:

MyTerribleFunction proc uses esi ebx ecx Param1,Param2,ParamX...
.if Param1==0
    mov eax,FALSE
    ret
.endif
;do something
mov eax,TRUE
ret
MyTerribleFunction endp

In that second example, TWO sets of POPS are generated for us, right before each RET statement.
It seems strange at first, but the more we learn about what our assembler actually generates in terms of opcodes, the more we can afford to relax and forget about it :)

Does that answer your question?
Posted on 2006-08-01 10:43:28 by Homer
Yes it does, i'll stick with pusha and eventually pushf as well and their epilogues since i don't know yet what stuff i should preserve from the code i'm jumping from.

I also got an error while attempting to save another ebp(lol i'm such a newb) after enter sets one by default(but i think i should be able to do so; since something about having multiple frames drafted my ears).
Posted on 2006-08-01 12:42:41 by w0lfshad3
w0lfshad3: you might as well stick with the standard intel-defined ABI... ebx,esi,edi,ebp must be preserved while eax,ecx,edx can be trashed. (preserve doesn't mean blindly push/pop, it means making sure register has same value on exit as on entry - so if you don't modify the register, "preserving" is automatic).

The same ABI also has return values in EAX or EDX:EAX depending on size.

For win32, keep the direction bit clear (if you STD, CLD) and the stack four-byte aligned, don't mess with segments/selectors and keep your data four-byte aligned as well.
Posted on 2006-08-01 14:05:01 by f0dder