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.
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
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
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
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.
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 ++.
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)
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
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
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.
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.
Thanks for all the answers. All clear now.
: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.
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.
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 RUN
TIME LIBRARY. Link does not check what code is behind *CRTStartup label - this is irrelevant. I just wanted to emphasize what this label symbolizes.
It used to be decided at .code segment as an entry point described on the PE File structure.