From time to time we get discussions about the virtues and vices of using the standard MASM PROC operative and a range of alternative methods to write a procedure in MASM. The idea of this topic is so such variations can be explained by various people who either design their own or use non-standard designs so that other members can hace a look at such variation without it being attached to specific topics where members are asking for help in the Campus.
In particular I would like to see the example that one of our senior members Ratch has spoken about on occasions so that everyone knows what he is speaking about.
Below is a simple example of a masm PROC, a manually coded stack frame, a proc with no stack frame and a proc with a stack frame and local variables. Below it is the disassembly of the masm PROC and the manually coded stack frame that use identical code apart from the variable addresses.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
masmproc PROTO :DWORD
.data
txt db "Text for MessageBox",0
ttl db "Title",0
.code
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke masmproc, 0 ; normal MASM procedure
push 1
call stframe ; manually coded stack frame
push 2
call noframe ; procedure with no stack frame
call sflocal ; manually coded stack frame with LOCAL vars
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
masmproc proc number:DWORD
fn MessageBox,0,str$(number),"masmproc",MB_OK
ret
masmproc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
stframe:
push ebp
mov ebp, esp
fn MessageBox,0,str$([ebp+8]),"stframe",MB_OK
leave
ret 4
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
noframe:
mov edx, [esp+4]
fn MessageBox,0,str$(edx),"noframe",MB_OK
ret 4
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
sflocal:
push ebp
mov ebp, esp
sub esp, 16 ; allocate local variable space
mov DWORD PTR [ebp-16], 0 ; windows handle
mov eax, OFFSET txt
mov DWORD PTR [ebp-12], eax
mov eax, OFFSET ttl
mov DWORD PTR [ebp-8], eax
mov DWORD PTR [ebp-4], MB_OK ; msgbox style
fn MessageBox,[ebp-16],[ebp-12],[ebp-8],[ebp-4]
leave
ret 4
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
00401021 fn_00401021: ; masmproc
00401021 55 push ebp
00401022 8BEC mov ebp,esp
00401024 681A304000 push 40301Ah
00401029 FF7508 push dword ptr [ebp+8]
0040102C E89F000000 call fn_004010D0
00401031 6A00 push 0
00401033 6830304000 push 403030h
00401038 681A304000 push 40301Ah
0040103D 6A00 push 0
0040103F E8F2000000 call jmp_MessageBoxA
00401044 C9 leave
00401045 C20400 ret 4
00401048 fn_00401048: ; manually coded stack frame
00401048 55 push ebp
00401049 8BEC mov ebp,esp
0040104B 6839304000 push 403039h
00401050 FF7508 push dword ptr [ebp+8]
00401053 E878000000 call fn_004010D0
00401058 6A00 push 0
0040105A 6850304000 push 403050h
0040105F 6839304000 push 403039h
00401064 6A00 push 0
00401066 E8CB000000 call jmp_MessageBoxA
0040106B C9 leave
0040106C C20400 ret 4