12

I am trying to create a helloworld program using only masm and not masm32 libs. Here is the code snippet:

.386
.model flat, stdcall
option casemap :none

extrn MessageBox : PROC
extrn ExitProcess : PROC

.data
        HelloWorld db "Hello There!", 0

.code
start:

        lea eax, HelloWorld
        mov ebx, 0
        push ebx
        push eax
        push eax
        push ebx
        call MessageBox
        push ebx
        call ExitProcess

end start

I am able to assemble this using masm:

c:\masm32\code>ml /c /coff demo.asm
Microsoft (R) Macro Assembler Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: demo.asm

However, I am unable to link it:

c:\masm32\code>link /subsystem:windows /defaultlib:kernel32.lib /defaultlib:user
32.lib demo.obj
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

demo.obj : error LNK2001: unresolved external symbol _MessageBox
demo.obj : error LNK2001: unresolved external symbol _ExitProcess
demo.exe : fatal error LNK1120: 2 unresolved externals

I am including the libs during linking, so not sure why it still says unresolved symbols?

UPDATE:

c:\masm32\code>link /subsystem:windows /defaultlib:kernel32.lib /defaultlib:user
32.lib demo.obj
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

demo.obj : error LNK2001: unresolved external symbol _MessageBox@16
demo.exe : fatal error LNK1120: 1 unresolved externals

UPDATE 2: Final working code!

.386
.model flat, stdcall
option casemap :none

extrn MessageBoxA@16 : PROC
extrn ExitProcess@4 : PROC

.data
        HelloWorld db "Hello There!", 0

.code
start:

        lea eax, HelloWorld
        mov ebx, 0
        push ebx
        push eax
        push eax
        push ebx
        call MessageBoxA@16
        push ebx
        call ExitProcess@4

end start
rkhb
  • 14,159
  • 7
  • 32
  • 60
Jumbo
  • 533
  • 3
  • 8
  • 15

2 Answers2

17

The correct function names are MessageBoxA@16 and ExitProcess@4.

Almost all Win32 API functions are stdcall, so their names are decorated with an @ sign, followed by the number of bytes taken up by their parameters.

Additionally, when a Win32 function takes a string, there are two variants: one that takes an ANSI string (name ends in A) and one that takes a Unicode string (name ends in W). You're supplying an ANSI string, so you want the A version.

When you're not programming in assembly the compiler takes care of these points for you.

Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
  • Thanks! This resolved one of the link errors but not the other.. see update – Jumbo Nov 08 '10 at 10:38
  • Awesome! worked perfectly now. I feel like such a n00b - can you suggest any docs / books where I can pick all this stuff up from? MSDN is too daunting to explore when you are a novice. – Jumbo Nov 08 '10 at 10:48
  • You may also want to refer Iczelion's Win32 ASM tutorials: http://win32assembly.online.fr/ – swatkat Nov 08 '10 at 10:49
  • 1
    I like Randall Hyde's stufF: http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/Win32Asm/index.html. He uses HLA, which is effectively a set of macros on top of raw MASM, but the principles are the same. – Tim Robinson Nov 08 '10 at 10:51
  • 1
    BTW, these are not noobie questions: with assembly, you're having to deal with a lot of annoying details that higher-level tools normally handle. – Tim Robinson Nov 08 '10 at 10:52
  • Thanks for all the answers! :) You are a life saver for me today. – Jumbo Nov 08 '10 at 11:05
  • @Jumbo, I think asking a new question for docs / books for Assembly would be very valid :) – default Nov 08 '10 at 11:12
  • you can use invoke to avoid push – justyy Oct 15 '13 at 17:25
5

Try adding this before .data segment:

include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
jyz
  • 6,011
  • 3
  • 29
  • 37