News:

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

How is the entry point decided?

Started by bf2, September 20, 2011, 05:00:45 PM

Previous topic - Next topic

bf2

How does the linker decide what the entry point of the executable should be?

I thought the main program should be enclosed by start and end start, but it is not so.

I have tried various combinations. Some work, some fail.

Combination 1 - arbitary label in caller instead of start, no label in procedure. Result: works fine.
INCLUDE \masm32\include\masm32rt.inc

.DATA
caption DB "Caption", 0
text DB 10 DUP(?)

.CODE
MyProc PROC
MOV EAX, 45
INVOKE dwtoa, EAX, ADDR text
INVOKE MessageBox, NULL, ADDR text, ADDR caption, MB_OK
RETN
MyProc ENDP

.CODE
caller:
INVOKE MyProc
INVOKE ExitProcess, NULL
END caller



Combination 2 - no label in caller or procedure. Result: assembly error 'END directive required at end of file'.
INCLUDE \masm32\include\masm32rt.inc

.DATA
caption DB "Caption", 0
text DB 10 DUP(?)

.CODE
MyProc PROC
MOV EAX, 45
INVOKE dwtoa, EAX, ADDR text
INVOKE MessageBox, NULL, ADDR text, ADDR caption, MB_OK
RETN
MyProc ENDP

.CODE
INVOKE MyProc
INVOKE ExitProcess, NULL



Combination 3 - no label in caller or procedure, but added an END directive after procedure. Result: assembles fine but linker returns the error 'unresolved external symbol _WinMainCRTStartup'.
INCLUDE \masm32\include\masm32rt.inc

.DATA
caption DB "Caption", 0
text DB 10 DUP(?)

.CODE
MyProc PROC
MOV EAX, 45
INVOKE dwtoa, EAX, ADDR text
INVOKE MessageBox, NULL, ADDR text, ADDR caption, MB_OK
RETN
MyProc ENDP
END

.CODE
INVOKE MyProc
INVOKE ExitProcess, NULL



Combination 4 - no label in caller or procedure, but added an END directive after both caller and procedure. Same result as 3.

INCLUDE \masm32\include\masm32rt.inc

.DATA
caption DB "Caption", 0
text DB 10 DUP(?)

.CODE
MyProc PROC
MOV EAX, 45
INVOKE dwtoa, EAX, ADDR text
INVOKE MessageBox, NULL, ADDR text, ADDR caption, MB_OK
RETN
MyProc ENDP
END

.CODE
INVOKE MyProc
INVOKE ExitProcess, NULL
END



Combination 5 - Both caller and procedure are enclosed in labels, but the caller is not enclosed in start/end start. Result: works fine.

INCLUDE \masm32\include\masm32rt.inc

.DATA
caption DB "Caption", 0
text DB 10 DUP(?)

.CODE
called:
MyProc PROC
MOV EAX, 45
INVOKE dwtoa, EAX, ADDR text
INVOKE MessageBox, NULL, ADDR text, ADDR caption, MB_OK
RETN
MyProc ENDP
END called

.CODE
caller:
INVOKE MyProc
INVOKE ExitProcess, NULL
END caller


Could someone kindly explain what's going on here?
Many thanks.

dedndave

there should only be one END directive in the program source
it should be at the end of all source code
it may specify an optional entry point

if you do not specify an entry point, i believe it will enter at the beginning of code as default (401000h)
that is probably why you are getting strange results
the masm32 library code for "dwtoa" is probably at that address   :P

jj2007

One more for playing.

include \masm32\include\masm32rt.inc

.code
AppName db "Masm32:", 0

SomeCode proc
MsgBox 0, "Ciao", "Hi", MB_OK
ret
SomeCode endp

MyStart: MsgBox 0, "Hello World", addr AppName, MB_OK
call SomeCode
exit

end MyStart   ; choose either this one...
;end SomeCode  ; or that one

drizz

Quote from: bf2 on September 20, 2011, 05:00:45 PM
How does the linker decide what the entry point of the executable should be?
I thought the main program should be enclosed by start and end start, but it is not so.
I have tried various combinations. Some work, some fail.
Combination 1 - arbitary label in caller instead of start, no label in procedure. Result: works fine.
END address
masm will add "/ENTRY:address" to the compiled obj file .drectve (linker directive) section,
do a "link -dump -all myobjfile.obj" to see

http://msdn.microsoft.com/en-us/library/wxy1fb5k(v=VS.71).aspx


Combination 2 - no label in caller or procedure. Result: assembly error 'END directive required at end of file'.
Combination 3 - no label in caller or procedure, but added an END directive after procedure. Result: assembles fine but linker returns the error 'unresolved external symbol _WinMainCRTStartup'.

you can either
1) end [[address]]
2) hardcoded labels "_mainCRTStartup" and "_WinMainCRTStartup" (cui / gui )
3) linking with c runtime
http://www.asmcommunity.net/board/index.php?topic=30386.msg213745#msg213745
4) linking with custom library
http://www.masm32.com/board/index.php?topic=8711.0


Combination 4 - no label in caller or procedure, but added an END directive after both caller and procedure. Same result as 3.
Combination 5 - Both caller and procedure are enclosed in labels, but the caller is not enclosed in start/end start. Result: works fine.

Anything after "end [[address]]"  is ignored
The truth cannot be learned ... it can only be recognized.

bf2

Drizz,
I sort of gather from the links you gave that the END [[label]] statement overrides _WinMainCRTStartup, but why is it customary to override it using START and END START? What does _WinMainCRTStartup do that we are trying to suppress?
Thanks.

ToutEnMasm

With the crt library the entry point of the program is in the library not in your source code.
an exe need                            start:    END START
a proc for a library need      PROC        ENDP       END       ;
To use the crt library you need to made a proc for a library.
The crt0.c give a name for the start point of you code.
To give this name the crt0.c made tests for console or windows aplications ++.

dedndave

WinMainCRTStartup is C compiler code that retrieves the command line and hInstance
(not sure - it may also initialize common controls and some MSVCRT stuff)
if you are writing an app in ASM, i suggest you do it yourself

you will see many examples on the forum that look something like this

WinMain PROC hInstance:HINSTANCE,hPrevInstance:HINSTANCE,lpCmdLine:LPSTR,nCmdShow:UINT

;main code

;result (exit code) returned in EAX
        ret

WinMain ENDP

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

Start:  INVOKE  GetModuleHandle,NULL
        mov     hInstance,eax
        INVOKE  GetCommandLine
        INVOKE  WinMain,hInstance,NULL,eax,SW_SHOWNORMAL
        INVOKE  ExitProcess,eax

        END     Start


all that is very unnecessary in ASM - it is totally a C compiler construct
also, the C startup code parses the EXE filename out of the command line and passes a pointer to the argument(s)

ToutEnMasm


Here is piece of text extrct from the crt0.c
First name is printed by the linker in case of error of name.
Second is the proc you must create.
Quote
*       Function:               User entry called:
*       mainCRTStartup          main
*       wmainCRTStartup         wmain
*       WinMainCRTStartup       WinMain
*       wWinMainCRTStartup      wWinMain

dedndave

on a side note.....

many ASM programmers learned the basics from Iczelion, either directly or indirectly
Iczelion probably learned by disassembling code that was compiled C   :P
that is why you see so much ASM code starting out this way

GregL

It's always been my understanding that either _mainCRTStartup (SUBSYSTEM:CONSOLE) or _WinMainCRTStartup (SUBSYSTEM:WINDOWS) are the entry point only if the C Run-Time library (CRT) is linked in. The CRT then passes on to what is specified after END.  If the CRT is not used, what is specified after END is used. If you don't specify anything after END you are asking for trouble, unless you are writing a library or secondary module of course.

drizz

Quote from: bf2 on September 21, 2011, 04:39:14 PM
Drizz,
I sort of gather from the links you gave that the END [[label]] statement overrides _WinMainCRTStartup, but why is it customary to override it using START and END START? What does _WinMainCRTStartup do that we are trying to suppress?
Thanks.
As I said *CRTStartup labels are hardcoded in the linker. Since linker is designed for C/C++, *CRTStartup is a label in the C runtime library - it puts library initialization before you get control automatically for c/c++ code. C/C++  is tied to the c runtime library.

Why is it customary to override it? Well it should be obvious, assembly programmers want control - no multi-kilobyte entry code. no dependencies winsxs or whatever comes with the new visual studio.

Nowadays linking with msvcrt is not a bad idea since msvcrt.dll is a part of the OS. In the old days it wasn't (IIRC).

Also rmember that hutch-- did not write ml/link etc. they are Microsoft tools.
The truth cannot be learned ... it can only be recognized.

bf2

Thanks for all the answers. All clear now.

hutch--

 :bg

> Iczelion probably learned by disassembling code that was compiled C  that is why you see so much ASM code starting out this way

No, he was competent in Win32 API code, that was the base for his tutorials. Win32 was reasonably well documented in win32.hlp and the rest is practice.

> Also rmember that hutch-- did not write ml/link etc. they are Microsoft tools.

I wonder where this nonsense was resurrected from, the copyright on both ML.EXE and Microsoft LINK.EXE make it very clear who is the author and copyright holder.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

hutch--

Now noting that various versions of LINK have all sorts of bits in them, DUMPBIN, EDITBIN and LIB, it is a mistake to assume that LINK is designed primarily to handle C runtime library code. You can for example build C Windows code with no runtime support.


void main()
    { etc ....
    }


MASM does it much the same way.

Attached is a VC2003 executable that uses the old VC98 version of MSVCRT, it does not use the C static runtime libraries at all.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

drizz

Quote from: hutch-- on September 22, 2011, 11:20:18 AM
> Also rmember that hutch-- did not write ml/link etc. they are Microsoft tools.

I wonder where this nonsense was resurrected from, the copyright on both ML.EXE and Microsoft LINK.EXE make it very clear who is the author and copyright holder.

I should have said it differently: m/link are a part of microsoft c/c++ compiler tools (present in DDK, WDK PSDK, SDK, VSTUDIO, VCTOOLKIT, VSEXPRESS etc etc, Like polink and poasm are a part of PellesC). So any answer to "why this" "why that" is more clear if this is understood.

Quote from: hutch-- on September 22, 2011, 11:39:40 AM
Now noting that various versions of LINK have all sorts of bits in them, DUMPBIN, EDITBIN and LIB, it is a mistake to assume that LINK is designed primarily to handle C runtime library code. You can for example build C Windows code with no runtime support.


void main()
    { etc ....
    }


MASM does it much the same way.

Attached is a VC2003 executable that uses the old VC98 version of MSVCRT, it does not use the C static runtime libraries at all.
@echo off

set bin=h:\vctoolkit\

set lib=%bin%lib\
set include=%bin%include\

%bin%bin\rc.exe rsrc.rc

if exist project2.exe del project2.exe
if exist project2.obj del project2.obj

%bin%bin\cl /c /O1 /Os /TC project2.c
%bin%bin\Link /SUBSYSTEM:WINDOWS /entry:main /libpath:%bin%lib @project2.rsp rsrc.res

dir project2.*

pause


Overriding entrypoint with "/entry:main" is exactly (As I said in my first post) what "start:" "end start" lines do in an asm file.

Quote from: drizz on September 21, 2011, 07:51:10 AM
Combination 1 - arbitary label in caller instead of start, no label in procedure. Result: works fine.
END address
masm will add "/ENTRY:address" to the compiled obj file .drectve (linker directive) section,
do a "link -dump -all myobjfile.obj" to see

http://msdn.microsoft.com/en-us/library/wxy1fb5k(v=VS.71).aspx

Once more and I'm done. Link searches for *CRTStartup symbol in the object files - it is hardcoded. This hardcoded name can be overridden with "/ENTRY". Clearly, hardcoded letters CRT mean  C RUNTIME LIBRARY. Link does not check what code is behind *CRTStartup label - this is irrelevant. I just wanted to emphasize what this label symbolizes.

The truth cannot be learned ... it can only be recognized.