0

I had been setting my application (MASM assembly language program) entry point via Visual Studio configurations, in the Project properties as:

Linker\System\SubSystem:    Windows (/SUBSYSTEM:WINDOWS)
Linker\Advanced\Entry Point:    WinMain

Any my main proc called WinMain (matching the above setting). It is a basic application that makes simple Windows API calls, e.g. MessageBoxA... and it works.

Now I'm building a Window application (in assembly), I read somewhere that I need to call the WinMain Windows API for an entry point.

I'm now confused! Which technique do I use to set the entry point to my application (exe)? The Windows API call 'WinMain' or the Visual Studio Linker entry point settings? And is the difference, i.e. C++ runtime vs OS?

Jester
  • 56,577
  • 4
  • 81
  • 125
OpcodePete
  • 887
  • 1
  • 14
  • 28
  • 1
    I am not aware of a `WinMain` API call ... can you post your source for that? I think you are misunderstanding something. – Jester Jan 21 '16 at 22:20
  • 1
    There is no WinMain API call, and even if there was you can't use it to set the entrypoint because you can only execute code after the entrypoint has already been entered (except for weird stuff that is certainly not relevant to this question) – harold Jan 21 '16 at 22:23
  • @Jester It looks like I have mistaken this MSDN page as a Win API call: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633559%28v=vs.85%29.aspx Looks just like a typical Win API call (except no Library & DLL specified), e.g. https://msdn.microsoft.com/en-us/library/windows/desktop/ms645505%28v=vs.85%29.aspx – OpcodePete Jan 21 '16 at 22:43
  • @harold Very logical point :) execute after the entry point. – OpcodePete Jan 21 '16 at 22:45
  • So I now read the WinMain article as a suggestion, i.e. call your main proc "Start", which 1) gets the main instance, 2) gets any command line params, then 3) call your "WinMain" proc which is another proc that contains the main chunk of your program, and finally 4) calls ExitProcess. Am I correct? – OpcodePete Jan 21 '16 at 22:51
  • 1
    The WinMain documentation says "The user-provided entry point for a graphical Windows-based application." In other words, WinMain is a function provided by the application. – Raymond Chen Jan 21 '16 at 22:52
  • 2
    Windows calls you. The operating system does not care what you name your entrypoint. It just makes a call to an address, the one that is listed in the EXE header. The linker writes that address into the header. To do that, it needs to know what you named your entrypoint function. Which is why you had to change the Linker > Advanced > Entry Point setting. You can name it anything you want. In a C++ program, the entrypoint must be located in the C runtime library to make sure the CRT gets initialized correctly, it is wWinMainCRTStartup. Which then calls WinMain(). – Hans Passant Jan 21 '16 at 22:54

1 Answers1

2

If you are using the C runtime library (which is usually the case when programming in C) then you must not specify the linker entry point yourself. If you do, the runtime library will not be properly initialized, and any runtime library calls (including those inserted by the compiler) may fail.

Instead, your main function should correspond to the relevant standard: WinMain() for a GUI application, or main() for a console application.

In an assembly language program that is not linked to the C runtime library, you should specify an entry point of your choosing.

The signature of the native entry point is

DWORD CALLBACK RawEntryPoint(void);

Important:

Returning from the raw entry point implicitly calls ExitThread (see this answer) which is not usually the right thing to do, because if the Windows API has created any threads that you don't know about, the process won't exit until they do. Note that the Windows API documentation does not always indicate when a particular API function may cause a thread to be created.

Instead, you should explicitly call ExitProcess. This is what the C runtime library does when you return from WinMain() or main().

Community
  • 1
  • 1
Harry Johnston
  • 35,639
  • 6
  • 68
  • 158