I've recently been trying to start with MASM. I'm running a 64-bit Windows 7 OS. I'm using the ml.exe and link.exe provided by MASM32 SDK (http://www.masm32.com/ (http://www.masm32.com/))
However, whenever I assemble my test.asm into an object file and link it, and then try to run the created exe, I get the windows error:
(http://puu.sh/hfE7s/3b960094d8.png)
32bit programs should be compatible with 64bit OS?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I looked in the the /masm32/ folder and found some examples that they provided. Here is one of their 32 bit programs that I'm trying to assemble and link:
; #########################################################################
.386
.model flat, stdcall
option casemap :none ; case sensitive
; #########################################################################
include \masm32\include\windows.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
; #########################################################################
;=============
; Local macros
;=============
szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text,0
lbl:
ENDM
m2m MACRO M1, M2
push M2
pop M1
ENDM
return MACRO arg
mov eax, arg
ret
ENDM
;=================
; Local prototypes
;=================
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
TopXY PROTO :DWORD,:DWORD
.data
szDisplayName db "Popup ListBox",0
CommandLine dd 0
hWnd dd 0
hInstance dd 0
lpfnWndProc dd 0
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax
; #########################################################################
WinMain proc hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD
;====================
; Put LOCALs on stack
;====================
LOCAL msg :MSG
LOCAL Wwd :DWORD
LOCAL Wht :DWORD
LOCAL Wtx :DWORD
LOCAL Wty :DWORD
mov Wwd, 150
mov Wht, 150
invoke GetSystemMetrics,SM_CXSCREEN
invoke TopXY,Wwd,eax
mov Wtx, eax
invoke GetSystemMetrics,SM_CYSCREEN
invoke TopXY,Wht,eax
mov Wty, eax
szText szClassName,"LISTBOX"
invoke CreateWindowEx,WS_EX_PALETTEWINDOW or WS_EX_CLIENTEDGE,
ADDR szClassName,
ADDR szDisplayName,
WS_OVERLAPPEDWINDOW or WS_VSCROLL or \
LBS_HASSTRINGS or LBS_NOINTEGRALHEIGHT or \
LBS_DISABLENOSCROLL, \
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInst,NULL
mov hWnd,eax
invoke SetWindowLong,hWnd,GWL_WNDPROC,ADDR WndProc
mov lpfnWndProc, eax
invoke GetStockObject,ANSI_FIXED_FONT
invoke SendMessage,hWnd,WM_SETFONT,eax,0
jmp @123
item1 db "This is item 1",0
item2 db "This is item 2",0
item3 db "This is item 3",0
item4 db "This is item 4",0
item5 db "This is item 5",0
item6 db "This is item 6",0
item7 db "This is item 7",0
item8 db "This is item 8",0
item9 db "This is item 9",0
item0 db "This is item 0",0
@123:
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item1
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item2
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item3
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item4
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item5
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item6
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item7
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item8
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item9
invoke SendMessage,hWnd,LB_ADDSTRING,0,ADDR item0
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd
;===================================
; Loop until PostQuitMessage is sent
;===================================
StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:
return msg.wParam
WinMain endp
; #########################################################################
WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
.if uMsg == WM_CLOSE
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
return 0
.endif
invoke CallWindowProc,lpfnWndProc,hWin,uMsg,wParam,lParam
ret
WndProc endp
; ########################################################################
TopXY proc wDim:DWORD, sDim:DWORD
shr sDim, 1 ; divide screen dimension by 2
shr wDim, 1 ; divide window dimension by 2
mov eax, wDim ; copy window dimension into eax
sub sDim, eax ; sub half win dimension from half screen dimension
return sDim
TopXY endp
; ########################################################################
end start
assembly/linking (im using this for reference https://msdn.microsoft.com/en-us/library/s0ksfwcf.aspx (https://msdn.microsoft.com/en-us/library/s0ksfwcf.aspx))
C:\Users\*\Desktop\ASM>ml /c /coff main.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: main.asm
***********
ASCII build
***********
C:\Users\*\Desktop\ASM>link main.obj test.exe
Neither produce any errors/warnings.
You didn't specify the subsystem.
If you are building a GUI application :
link /SUBSYSTEM:WINDOWS main.obj
For a console application :
link /SUBSYSTEM:CONSOLE main.obj
Hi Sieg,
Erol gave the right answer in post #1. The subsystem is an important information. And yes, MASM32 runs fine under Windows-64. Welcome to the forum.
Gunther
Quote from: Sieg on April 17, 2015, 05:29:06 AM
C:\Users\*\Desktop\ASM>link main.obj test.exe
Neither produce any errors/warnings.
First, you should get this error:
LINK : fatal error LNK1221: a subsystem can't be inferred and must be defined
Second,
link main.obj test.exe
treats test.exe as an input file. The right syntax is /out:test.exe
Welcome to the forum :icon14:
Hi, thank you for the responses! I tried the recommended fixes; however, it seems to only give me an error when trying to link.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\*>link main.obj /out:test.exe /SUBSYSTEM:WINDOWS
link: extra operand `/SUBSYSTEM:WINDOWS'
Try `link --help' for more information.
C:\Users\*\Desktop\ASM>link /SUBSYSTEM:WINDOWS main.obj
link: cannot create link `main.obj' to `/SUBSYSTEM:WINDOWS': File exists
Thank you again
Quote from: Sieg on April 17, 2015, 06:32:51 AMI never got such an error
Indeed, the linker does not produce an error for link foo.obj foo.exe, if foo.exe exists. This is very odd, because foo.exe without the /OUT: option is just an input file.
Quote from: jj2007 on April 17, 2015, 08:20:11 AM
Quote from: Sieg on April 17, 2015, 06:32:51 AMI never got such an error
Indeed, the linker does not produce an error for link foo.obj foo.exe, if foo.exe exists. This is very odd, because foo.exe without the /OUT: option is just an input file.
When
foo.exe does not exist, it creates
foo.exe for me when I type
link foo.obj foo.exe into the command line, so I assumed
foo.exe created by LINK would be the output/linked file.
Quote from: Sieg on April 17, 2015, 09:21:23 AMWhen foo.exe does not exist, it creates foo.exe for me when I type link foo.obj foo.exe into the command line, so I assumed foo.exe created by LINK would be the output/linked file.
Interesting. Can anybody else reproduce this behaviour?
Quote from: jj2007 on April 17, 2015, 03:24:29 PM
Quote from: Sieg on April 17, 2015, 09:21:23 AMWhen foo.exe does not exist, it creates foo.exe for me when I type link foo.obj foo.exe into the command line, so I assumed foo.exe created by LINK would be the output/linked file.
Interesting. Can anybody else reproduce this behaviour?
I feel like I did something wrong with installation, since I'm the only one getting this problem?
All I did was: download the MASM32 SDK from this website, and I went through the install. I got no errors, and the install success screen came up at the end; however, for some reason 30 seconds after the installation completed fully I got the windows message that the program may not have installed correctly
Looked something like this
(http://cdn.ghacks.net/wp-content/uploads/2010/01/program_compatibility_assistant.jpg)
But I'm certain that it's a false positive, and that everything installed correctly. So I just clicked "this program installed correctly."
And after that, the only thing I did next was add
C:\masm32\bin to my system's PATH environment variable.
Did I miss any steps in setuping MASM for my computer?
You did everything right. Now copy the text below, paste it into a \masm32\qEditor window, save as Test.asm, and do "Project/Build all".
include \masm32\include\masm32rt.inc
.code
AppName db "Masm32:", 0
start: MsgBox 0, "Hello World", addr AppName, MB_OK
exit
end start
Quote from: jj2007 on April 17, 2015, 03:38:53 PM
You did everything right. Now copy the text below, paste it into a \masm32\qEditor window, save as Test.asm, and do "Project/Build all".
include \masm32\include\masm32rt.inc
.code
AppName db "Masm32:", 0
start: MsgBox 0, "Hello World", addr AppName, MB_OK
exit
end start
Assembled and linked just fine. The exe created the msg box
Hi! I seem to have figured out the issue, but am still not sure what the source of the issue was.
Whenever I use a direct path to the Link.exe in the command line, such as C:\masm32\bin\Link /SUBSYSTEM:WINDOWS main.obj, it assembles perfectly. :greenclp:
But if I just use the command link in the command line without providing a direct path, it's as if I have a different version of link which is causing the issues.
However, in my environmental variables, I have the PATH C:\masm32\bin added, so I'm not sure how link in the command-line is using a different .exe other than the one in \masm32\bin.
I have MinGW installed (for GCC), and I'm not sure if that was the issue. I removed C:\MinGW\bin from my path, and the issue still exists. So I don't think that is causing the problem?
Do you notice any possible paths that may be including a different version of Link?
LOCAL PATH VAR
C:\Ruby200\bin;C:\Python27\;C:\Users\*\AppData\Roaming\npm;C:\Program Files\Java\jdk1.8.0_25\bin;C:\nasm\nasm-2.11.08
SYSTEM PATH VAR (removed quite a bit of default paths)
C:\Program Files\nodejs\;C:\sqlite3;C:\ruby\devkit\bin;C:\mysql-5.6.19-win32\bin;C:\Program Files (x86)\nodejs\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files (x86)\Livestreamer;C:\Program Files (x86)\Skype\Phone\;C:\masm32\bin
Thanks!
Quote from: Sieg on April 18, 2015, 06:38:17 AMDo you notice any possible paths that may be including a different version of Link?
Give me remote access to your computer, and I will notice possible paths.
dir /S link.exe is a useful command in this context.
Running
where link
in a command prompt will print out the paths of exe, script, and batch files called link that are in the path.
FWIW, I don't bother with PATH variables, just always specify the full path in command line, i.e. \masm32\bin\Link. Of course it's in a batch file, I don't type it out by hand. (I also use the menus when applicable, and other techniques, but my main tool is a batch file). After all there's a lot more to it than just the path: there are options like SUBSYSTEM, also more complicated projects have multiple .asm files and .obj's; you're not going to type all that out, are you? (Some people use RadAsm or similar, that's another story). The point is, if batch file is more-or-less inevitable, there's no problem with including the explicit path, so why not just do that, and ignore PATH environmental variable?
FWIW here's an example of a batch file I use (included in a recent "trig" project I posted)
@echo off
if exist "%1.obj" del "%1.obj"
\bin\JWasm -coff -nologo %1.asm
rem \masm32\bin\ml /c /coff "%1.asm"
if errorlevel 1 goto theend
if exist "%1.exe" del "%1.exe"
\masm32\bin\link /nologo /subsystem:console %1.obj
if errorlevel 1 goto theend
%1
:theend
It's named "do.bat" and I simply type "do trig" to assemble/link/run trig.asm (for example). I dunno, what's wrong with that approach?
Quote from: adeyblue on April 18, 2015, 07:00:10 AM
Running
where link
in a command prompt will print out the paths of exe, script, and batch files called link that are in the path.
Ahhh, this did the trick! Turns out that Ruby has it's own link.exe that was causing the issue.
(http://puu.sh/hhuSy/571ba63643.png)
Quote from: rrr314159 on April 18, 2015, 07:14:19 AM
FWIW, I don't bother with PATH variables, just always specify the full path in command line, i.e. \masm32\bin\Link. Of course it's in a batch file, I don't type it out by hand. (I also use the menus when applicable, and other techniques, but my main tool is a batch file). After all there's a lot more to it than just the path: there are options like SUBSYSTEM, also more complicated projects have multiple .asm files and .obj's; you're not going to type all that out, are you? (Some people use RadAsm or similar, that's another story). The point is, if batch file is more-or-less inevitable, there's no problem with including the explicit path, so why not just do that, and ignore PATH environmental variable?
FWIW here's an example of a batch file I use (included in a recent "trig" project I posted)
@echo off
if exist "%1.obj" del "%1.obj"
\bin\JWasm -coff -nologo %1.asm
rem \masm32\bin\ml /c /coff "%1.asm"
if errorlevel 1 goto theend
if exist "%1.exe" del "%1.exe"
\masm32\bin\link /nologo /subsystem:console %1.obj
rem if errorlevel 1 goto theend
%1
:theend
It's named "do.bat" and I simply type "do trig" to assemble/link/run trig.asm (for example). I dunno, what's wrong with that approach?
Thanks for the suggestion! I setup a keybind shortcut in Notepad++ to run the commands to assemble and link a file, but I still wanted to find the issue as to where the unwanted
link.exe was coming from. :)
(http://puu.sh/hhv92/78f16ad352.png)
Thank you everyone for the support & help. :)
Quote from: adeyblue on April 18, 2015, 07:00:10 AM
Running
where link
in a command prompt will print out the paths of exe, script, and batch files called link that are in the path.
I keep learning :t
But I agree with rrr314159 that specifying the full path is the better choice. Environment variables are notoriously messy. Does anybody need
wbem in the path? (http://www.pcreview.co.uk/threads/do-i-need-wbem-in-path-statement.2330116/) It sucks, Microsoft! My path is spoiled by various a**holes like NVIDIA, TDM-GCC and three long and only marginally different versions of c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn (and no, "Binn" is not a misspelled "bin"). Only a handful of applications use this stone age technology.
Quote from: SiegAhhh, this did the trick! Turns out that Ruby has it's own link.exe that was causing the issue.
- Congrats!
Quote from: Sieg...I still wanted to find the issue as to where the unwanted link.exe was coming from.
- that's the right attitude! Leave an issue like that unresolved, and someday it will bite u in the ***
Quote from: jj2007But I agree with rrr314159...
- also the right attitude! :biggrin:
Quote from: rrr314159 on April 18, 2015, 08:23:36 AMQuote from: jj2007But I agree with rrr314159...
- also the right attitude! :biggrin:
:eusa_naughty:
There is a reason why MASM32 is built with full paths, it is so it can run in multiple environments where you can have different versions of MASM32, different versions of VC and as long as you specify complete paths instead of using environment variables, none interact with the other so you don't get these problems. The only place you set environment variables is if you write a batch file with a number of SET commands that start and finish with the duration of the batch file running.
I routinely run and develop on Win7 64 so its not a MASM32 problem, its a configuration problem.