3 questions:

1. Is it possible to make MASM generate reference for locals instead of ?

2. How to turn off _temporary_ generation of epilogue code
for or how to turn it back without suppling macro.

a1 proc
OPTION EPILOGUE:NONE ;

ret
..
...
ret


;
OPTION EPILOGUE : __? ; now I need to turn it on

ret; exit
endp

3. How to make MASM use pop instead of 'bad' instruction "leave"
in the epilogue code.
Posted on 2002-06-24 13:32:45 by Sergo
HERE is a more advanced demonstration that answers most of your questions. It is not possible to have MASM automatically use instead of creating the stack frame. Chapter 9 of the MASM manual (towards the end) is a good read.
Posted on 2002-06-24 13:52:52 by bitRAKE
Here's a sample code on using locals without frames:
myfunc PROC

sub esp, 20 ;Allocate 20 bytes for our variable
mov DWORD PTR [esp], "lleH"
mov DWORD PTR [esp+4], "rC o"
mov DWORD PTR [esp+8], " leu"
mov DWORD PTR [esp+12], "lroW"
mov BYTE PTR [esp+16], "d"
mov BYTE PTR [esp+17], 0
lea eax, [esp] ;Load the address of the variable
invoke MessageBox, NULL, eax, NULL, MB_OK
add esp, 20
retn
myfunc ENDP
Here's a screenshot from a disasm view, to prove that there are no frames.
Posted on 2002-06-24 14:16:08 by stryker
I don't know why you have to make things so hard, stryker. :grin:
proto9 typedef proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

invoke proto9 PTR [MessageBox], 0, ADDR [esp+8], 0, 0, 6C6C6548h, 7243206Fh, 206C6575h, 6C726F57h, 2E64h
add esp,20
Posted on 2002-06-24 17:02:09 by bitRAKE
lol!!! :grin: I like it this way!

I like that code above too. Never tried that yet!!! :)
Posted on 2002-06-24 17:36:59 by stryker
Can't you make macros for push and pop which keeps track of the offset to the locals. But that would mean that you couldn't push and pop as you want.
Posted on 2002-06-27 06:25:12 by gliptic
gliptic, yes and it works except for loops that push/pop.
Posted on 2002-06-27 06:48:21 by bitRAKE
What are the internal names for default prologue epilogue macros?
For example
OPTION EPILOGUE: default.

BTW can anybody suggest a link to MASM Programmer's Guide in one downoadable file.
BTW, Intel recommend use for leaf procedures ( ebp only for debug purposes )and avoid using complex instructions like 'leave' (also mov , const
comparing to push ). So comparing to the code generated by compilers in optimized mode (I checked cl.exe /O2 ) , code produced by ASSEMBLER ( MASM) using default macros doesn't look very good. :(
Posted on 2002-06-29 11:04:40 by Sergo
AMD recommends using LEAVE instruction... Now what? :confused:
Posted on 2002-06-29 17:31:09 by minimoog
Can ebp be zero out. Can i kill it sometime or change it. I think someone said he did something like that but did not explain how... i'm not sure...
Posted on 2002-06-29 20:57:22 by cmax

3 questions:

1. Is it possible to make MASM generate reference for locals instead of ?

2. How to turn off _temporary_ generation of epilogue code
for or how to turn it back without suppling macro.

3. How to make MASM use pop instead of 'bad' instruction "leave"
in the epilogue code.
1. No

2. The defaults are turned on with:
OPTION PROLOGUE:PROLOGUEDEF
OPTION EPILOGUE:EPILOGUEDEF

3. You have to write a custom epilogue macro for this.

What are the internal names for default prologue epilogue macros?

BTW, Intel recommend use for leaf procedures ( ebp only for debug purposes )and avoid using complex instructions like 'leave' (also mov , const comparing to push ). So comparing to the code generated by compilers in optimized mode (I checked cl.exe /O2 ) , code produced by ASSEMBLER ( MASM) using default macros doesn't look very good. :(
Sergo, I missed answering question two directly, but the fact that you asked the same question again indicates you did not look at my code. It is not complete, but there is still something to learn from it. Please take note of the fact prologue / epilogue examples for MASM are very rare.

MASM is old compared to VC++ and is updated less frequently. It is left up to the programmer to create more optimal code than the outdated code produced by the HL syntax. It still does well on an Athlon CPU. A replacement for MASM is long overdue, but it is not an easy task - MASM is very complex.
Posted on 2002-07-14 03:07:37 by bitRAKE
Here are a couple of simple macros that solve the problem of stack entry and exit. The assigned variable in one holds its value in the next so the value for the byte count in the first used on esp can be used again in the next one to correct the stack.


; #########################################################################

.486
.model flat, stdcall
option casemap :none ; case sensitive

; #########################################################################

proc_entry MACRO bytes:REQ
LOCAL start
start equ <sub esp, >
var = bytes ;; assignment works across different macros
start CATSTR start,%var ;; use it here locally
start
ENDM

proc_exit MACRO
LOCAL end
end equ <add esp, >
end CATSTR end,%var ;; use it again in next macro
end
ENDM

; #########################################################################

.code

start:

proc_entry 20

xor eax, eax

proc_exit

; #########################################################################

end start

This generates the code,


00401000 start:
00401000 83EC14 sub esp,14h
00401003 33C0 xor eax,eax
00401005 83C414 add esp,14h


Regards,

hutch@movsd.com
Posted on 2002-07-14 07:55:51 by hutch--
Condensed Version:
proc_entry MACRO bytes:REQ

;; assignment works across different macros
var = bytes
sub esp, bytes
ENDM

proc_exit MACRO
% add esp, var
ENDM
Nesting would be nice. :)


Super Condensed Version:
proc_entry MACRO bytes:REQ

sub esp, bytes

;; assignment works across different macros ;)
proc_exit MACRO
add esp, bytes
ENDM
ENDM
:grin: :grin:
Posted on 2002-07-14 08:08:04 by bitRAKE


; #########################################################################

proc_entry MACRO name,bytes:REQ
LOCAL start
name:
start equ <sub esp, >
var = bytes ;; assignment works across different macros
start CATSTR start,%var ;; use it here locally
start
ENDM

proc_exit MACRO
LOCAL end
end equ <add esp, >
end CATSTR end,%var ;; use it again in next macro
end
retn
ENDM

; ###################################

.code

start:

call proc1

proc_entry proc1, 20
call proc2
proc_exit

proc_entry proc2, 20
mov eax, 1
proc_exit

Generates the code,


00401000 start:
00401000 E800000000 call fn_00401005
00401005 fn_00401005:
00401005 83EC14 sub esp,14h
00401008 E804000000 call fn_00401011
0040100D 83C414 add esp,14h
00401010 C3 ret
00401011 fn_00401011:
00401011 83EC14 sub esp,14h
00401014 B801000000 mov eax,1
00401019 83C414 add esp,14h
0040101C C3 ret

Regards,

hutch@movsd.com
Posted on 2002-07-14 08:17:49 by hutch--
Well, I mean - nesting:
proc_entry 20


xor eax, eax

proc_entry 20
xor eax, eax
proc_exit
proc_exit
With no CALL overhead.
Posted on 2002-07-14 08:20:25 by bitRAKE
Yes,

you are right, the two macros must be symetrical but this is not really a problem as MASM requires this anyway in its own PROC syntax.

I would imagine that a proc nested in the way your example is done would need to be written differently. A jump to a label and a following RETN within the scope of an existing proc is common use so its a matter of whether the stack needs to be preserved within an existing proc anyway.

Regards,

hutch@movsd.com
Posted on 2002-07-14 08:41:29 by hutch--

AMD recommends using LEAVE instruction... Now what? :confused:


Not just AMD. Intel recommends it for P6, too. (I do not have Intel's optimization guide for P5, so I don' know about P5.) In fact, leave is a 3 micro-op instruction and we don't need to worry about decoding bottleneck on P6. Moreover, it is only one byte long and it is logically plausible that using leave is better than mov esp,ebp / pop ebp combination. I don't know if it is actually better, but I don't care, because leave is usually followed by ret and I don't think I would enjoy any big speed gain by not using leave. :)
Posted on 2002-07-15 17:08:52 by Starless
I agree with Starless here, if a block of code is small enough and speed critical enough, you write it inline and forget about using the call/ret syntax or the stack. Its when you want block code that can be accessed from a range of different places that you use a procedure.

I have yet to see any blazing speed differences in stack entry and exit and LEAVE does generate small code that seems to work fine.

Regards,

hutch@movsd.com
Posted on 2002-07-15 20:54:46 by hutch--