News:

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

starting at the end

Started by redskull, April 02, 2008, 12:35:25 AM

Previous topic - Next topic

redskull

Hey all -

I wanted to pick all the genius brains around here, and ask what everyones opinion is on how to 'start' a program.  It seems to me that a programmer has two options, either start at the beginning with a label, or start at the 'end' with a procedure, for lack of better terms.  Since a picture is worth 1000 words:

.code
starthere:
  <do stuff>
 
proc one
endp

end



vs

.code

proc one
<do other stuff>
endp

proc main
<do stuff>
endp

end main


where the 'main' function is always the entry point, much like a C program.  Does anybody have opinions or personal preference as to which is better, worse, faster, clearer, cleaner, more modular, etc, etc? Thank you in advance.

-alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

NightWare

for me the second, no need to define proto...  :bg

MichaelW

I prefer to do the obvious and start at a label named start. Starting at a procedure is a non-obvious variation of starting at a label that has never made much sense to me. It forces you to terminate your application with a return, or code a procedure that cannot actually be called. Depending on the code I might place the start label at the start of the code section or somewhere in the middle. It makes no sense to place the start label at the end of the code.
eschew obfuscation

jj2007

Agree with Michael. It is easier to read a program that starts with
.code
start:
The second option is feasible, but even then you are required to type the Main (or MyMain - you are free to choose whatever name) three times, see below.

\masm32\include\masm32rt.inc

.code

AppName db "Test app with no data section",0
AskUser db "Try to write into the code section?",0
MsgText db "Big problem!",0

MyMain proc
.if rv(MessageBox,NULL,addr AskUser,addr AppName,MB_YESNO)==IDYES
  lea edx,MsgText
  mov eax," ooN" ; "Big " becomes "Noo " problem
  mov [edx],eax ; and here it will crash if you did not set .code to ERW
.endif
invoke MessageBox,NULL,addr MsgText,addr AppName,MB_YESNO
invoke ExitProcess,eax
MyMain endp
end MyMain

this linker option makes the code section writable:
/SECTION:.text,ERW


MichaelW

Perhaps instead of "a procedure that cannot actually be called" I should have used "a procedure that is not actually called". In your code the:

MyMain proc
MyMain endp

Could be replaced with a simple:

MyMain:
eschew obfuscation

jj2007

Quote from: MichaelW on April 02, 2008, 07:50:55 AM
Perhaps instead of "a procedure that cannot actually be called" I should have used "a procedure that is not actually called". In your code the:

MyMain proc
MyMain endp

Could be replaced with a simple:

MyMain:


Indeed - that's why I consider the Main proc a fake solution. Windows actually checks for the end <label> directive and looks up the corresponding <label> - and does not care whether it's a standard label or a proc. In the example below, MyOther is being happily ignored.

include \masm32\include\masm32rt.inc

.code

AppName db "Test app with no data section",0
AskUser db "Try to write into the code section?",0
MsgText db "Big problem!",0

MyOther proc
invoke MessageBox, NULL, chr$("Oops, wrong procedure!"), addr AppName, MB_OK
ret
MyOther endp

MyMain proc
.if rv(MessageBox,NULL,addr AskUser,addr AppName,MB_YESNO)==IDYES
  lea edx,MsgText
  mov eax," ooN" ; "Big " becomes "Noo " problem
  mov [edx],eax ; and here it will crash if you did not set .code to ERW
.endif
invoke MessageBox,NULL,addr MsgText,addr AppName,MB_YESNO
invoke ExitProcess,eax
MyMain endp
end MyMain

u

Completely irrelevant stuff >_< . It's not like it's gonna improve the user's experience, or break sometimes if it ran the first time (and is sanely coded).

And jj2007, it's not Windows that looks for that label, it's MASM :P . [name: .... end name] is the construct to specify the entry-point in an executable.

If it's all about easy-to-read, then nothing can beat


main proc
   ...
   ret
main endp

start:
  invoke main
  invoke ExitProcess,0
end start

As it is standard C everybody knows :P. And it's rare to not need local params in main(). And it's much cleaner/easier to think in terms of "ret" than ExitProcess.
Please use a smaller graphic in your signature.

jj2007

Quote from: Ultrano on April 02, 2008, 11:31:19 AM
And jj2007, it's not Windows that looks for that label, it's MASM :P . [name: .... end name] is the construct to specify the entry-point in an executable.
You are right, of course.

Vortex

Another example is to use an external startup module :

include     AppEntryPoint.inc

.data
message     db 'Command-line parameter = %s',0
caption     db 'Hello',0

.data?
buffer      db 256 dup(?)

.code

WinMain PROC hInstance:DWORD,hPrevInstance:DWORD,lpCmdLine:DWORD,nCmdShow:DWORD

    invoke  wsprintf,ADDR buffer,ADDR message,lpCmdLine
    invoke  MessageBox,0,ADDR buffer,ADDR caption,MB_OK
    ret

WinMain ENDP

END

[attachment deleted by admin]

MichaelW

You can also use what is apparently a linker default:

public mainCRTStartup
...
mainCRTStartup:
...
end

Or:

mainCRTStartup proc
...
mainCRTStartup endp
...
end


eschew obfuscation