masm32 linker does not create executable - linker

I installed masm32 on my Windows XP SP3 machine. I downloaded masm32 from here:
http://www.masm32.com/masmdl.htm
Installed it. I added the path, C:\masm32\bin to the PATH environment variable. Now, I am trying to assemble and link an example program. It creates the object file but does not create the executable file.
sample program:
include \masm32\include\masm32rt.inc
.data
MyTitle db "ASM!",0
MyText db "Some Text!",0
.code
start:
push 0
push offset MyTitle
push offset MyText
push 0
call MessageBoxA
call ExitProcess
end start
Also, please note that the default link.exe file which was present in the c:\masm32\bin directory was throwing an error while linking as shown below:
Assembling: sample.asm
***********
ASCII build
***********
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
/z2
"sample.obj+"
"sample.obj"
"sample.exe"
NUL
LINK : warning LNK4044: unrecognized option "z2"; ignored
LINK : fatal error LNK1181: cannot open input file "sample.obj+"
I got another version of link.exe from here:
http://download.microsoft.com/download/vc15/Update/1/WIN98/EN-US/Lnk563.exe
when I assemble and link using the following command:
ml.exe sample.asm sample.obj
It gives the error:
Assembling: sample.asm
***********
ASCII build
***********
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
Object Modules [.obj]: sample.obj+
Object Modules [.obj]: "sample.obj"
Run File [sample.exe]: "sample.exe"
List File [nul.map]: NUL
Libraries [.lib]:
Definitions File [nul.def]:
LINK : fatal error L1104: \masm32\lib\masm32.lib : not valid library

Well, you definitely don't want to use the Segmented linker, this is for 16bit code. Continue using the Incremental Linker Version 5.12.8078
So, your getting an obj file? That is what ML.exe does. It is the MASM Assembler and it will Assemble your code into an obj file that you pass to the linker of your choice to create the exe. I say the linker of your choice, since there are a few linkers that you can use all with their own pros and cons.
To create an object file: ml /c /coff /Cp sample.asm
The /c option tells ml to Assemble only and not attempt to link
The /Cp option tells ml to preserve the case of all identifiers
/coff creates the obj file in the Common Object File Format, this is what we use for x86 on Windows.
Now, you need to link the obj file into the exe: link /subsystem:windows sample.obj
/subsystem:windows creates a GUI Windows exe. Change to console to create a console based app (NOT the same as a DOS app)

Related

C source code, Watcom Compiler and EMU8086

How can I get the Watcom compiler (the forked version 2.0 beta which runs on 64-bit hosts) to output 8086 assembly source code in an ASM file? Running wcc -0 main.c from the command prompt produces just the OBJ file.
As a side note, my main task it to convert C source code to assembly code that I can run with EMU8086 (instead of writing the actual assembly code). I am hoping the ASM file generated by Watcom would run without modification (copy-paste) in EMU8086.
I don't see a way to get the Watcom compiler to generate an ASM file directly, but you should be able to use the Watcom disassembler (wdis) to generate an assembly listing from the object file produced by the compiler. In this case you would run something like wdis -l main to read main.obj and produce a file named main.lst that contains an assembly language listing.
If you recompile main.c with a -d1 or -d2 option to place extra debugging data into the main.obj file then you can use the disassembler's -s option to have the assembly language listing interpersed with comments showing the original C source from main.c.
To get the disassembler to omit descriptive comments and just give a plain disassembly that should be acceptable as a source file for the Watcom assembler, give the -a option to the disassembler. This option will also causes the disassembler's output to be written into main.asm rather than main.lst. Sorry, I have no idea whether this output will be directly consumable by EMU8086.
This is all discussed in the Open Watcom C/C++ User Guide and C/C++ Tools User Guide linked from http://www.openwatcom.com/doc.php

How to compile a 64-bit dll written in C?

I have a Java program which makes use of some native function calls to speed up video encoding. It requires a DLL, which I will write in C (I have just a test one right now).
When I compile the DLL with cl /I "java-path/include" /"java-path/include/win32" -DL -ML Main.c -FeTest.dll it compiles, but I get a 32-bit DLL. After I did some research on the internet, I found out that I would need a 64-bit DLL instead.
After more research, I have found this post which is the only one for C (even C++ was hard to find), but this only works if you are writing/building via Visual Studio 2010. I am using Elipse for the Java, CLion for the C, and compiling via the "Developer Command Prompt." so this does not work for me. How might I recompile as a 64-bit DLL?
EDIT: I am using the cl.exe that comes with Visual Studio 2017
UPDATE: I found the 64-bit cl.exe under C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin\Hostx64\x64\cl.exe, however when running it, I get an error that the library machine type (x86) conflicts with the target type (x64). How do I change the library machine type?
As I explained at the beginning of [SO]: How to build a DLL version of libjpeg 9b? (#CristiFati's answer) (bullets from 1. Prepare the ground section), there are different ways to deal with building from command line in VStudio. I'm going to focus on vcvarsall.bat. More details on [MSDN]: Setting the Path and Environment Variables for Command-Line Builds (It's VStudio2015 as VStudio2017 link is broken). I prepared a dummy example.
code.c:
#include <stdio.h>
#include "jni.h"
__declspec(dllexport) int func() {
JavaVMInitArgs args;
printf("Pointer size: %lld bits\n", sizeof(void*) * 8);
printf("JNI_GetDefaultJavaVMInitArgs returned: %d\n", JNI_GetDefaultJavaVMInitArgs(&args));
return 0;
}
Build:
e:\Work\Dev\StackOverflow\q050164687>"c:\Install\x86\Microsoft\Visual Studio Community\2017\VC\Auxiliary\Build\vcvarsall.bat" amd64
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.6.6
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
e:\Work\Dev\StackOverflow\q050164687>dir /b
code.c
e:\Work\Dev\StackOverflow\q050164687>cl /nologo /LD /I"c:\Install\x64\Oracle\Java\jdk1.8.0_152\include" /I"c:\Install\x64\Oracle\Java\jdk1.8.0_152\include\win32" /DWIN64 /DWIN32 code.c /link /LIBPATH:"c:\Install\x64\Oracle\Java\jdk1.8.0_152\lib" /OUT:dummy.dll jvm.lib
code.c
Creating library code.lib and object code.exp
e:\Work\Dev\StackOverflow\q050164687>dir /b
code.c
code.exp
code.lib
code.obj
dummy.dll
Notes:
My vcvarsall path is custom, because I installed VStudio2017 under "C:\Install\x86\Microsoft\Visual Studio Community\2017". Default path is "%SystemDrive%\Program Files (x86)\Microsoft Visual Studio\2017\Community"
After running vcvarsall, I don't have to specify to cl.exe (or link.exe):
The full path
Build options (architecture specific, including paths)
I still have to specify things that it doesn't know about (like Java stuff)
In order to test the newly built .dll, I'm going to use Python, as it's easier than writing another .c program that uses it
Since I linked the .dll to jvm.lib, at runtime it will need jvm.dll, so I'm adding its path into %PATH%
I built my code with VStudio2017 (VCRuntime14.0), but jvm.dll is linked to VCRuntime10.0 (VStudio2010), meaning that there will be (at least) 2 VCRuntimes loaded in my program. That is to be avoided as it could lead to all kinds of nasty problems
e:\Work\Dev\StackOverflow\q050164687>set PATH=%PATH%;c:\Install\x64\Oracle\Java\jdk1.8.0_152\jre\bin\server
e:\Work\Dev\StackOverflow\q050164687>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe"
Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> dummy = ctypes.CDLL("dummy.dll")
>>> dummy.func()
Pointer size: 64 bits
JNI_GetDefaultJavaVMInitArgs returned: -1
0
>>>

Microsoft linker spontaneously creating library

I'm trying to compile a C program (specifically, the Python interpreter) as a plain statically linked 64-bit Windows binary. My command line looks like this:
cl /DPy_BUILD_CORE ... /link Advapi32.lib Shell32.lib User32.lib
where ... is the long list of source files and include directory specifications, and the library specifications I added as necessary to fix unresolved symbol errors. I'm getting linker output that looks like (after the C compiler has finished running):
Microsoft (R) Incremental Linker Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:getbuildinfo.exe
Advapi32.lib
Shell32.lib
User32.lib
getbuildinfo.obj
(lots more .obj's)
Creating library getbuildinfo.lib and object getbuildinfo.exp
... and then a weird error that I'm still trying to figure out, but maybe I might have a better chance if I understand another aspect of the behavior of the linker here.
Why is it creating a library? I didn't tell it to do that. It's only supposed to be creating a .exe.
In particular, I tried a small test case with just a couple of trivial C source files and otherwise the exact same command line, and it behaved as expected, creating only the .exe and not trying anything with libraries. The only differences are in the number and contents of the C source files, but I wouldn't have thought the contents of a C source file could change the behavior of the linker.
What am I missing?

Linking programs

I have been trying to compile an asm file with tasm running on windows XP.
Tasm32 version - Turbo Assembler Version 5.0 Copyright (c) 1988, 1996 Borland International
Turbo Link Version 1.6.71.0 Copyright (c) 1993,1996 Borland International
With my current directory set to tasm\bin I have been able to do the following-
TASM32 /m29A /ml filename.asm
This generates the normal .Obj file. So far so good. Then I try to link using -
TLINK32 -Tpe -aa -x filename.obj,,,"kernel32.lib"
I am using the appropriate path to the kernel32.lib
But it is throwing up the following errors -
Fatal: Unable to open file 'filename.obj,,,C:\Program Files\Microsoft SDKs\Windo
ws\v6.0A\Lib\Kernel32.lib'
I have very little knowledge of asm and did Google around for a solution but I can't seem to find one. It seems that the linker is taking everything to be one single file.
Any help will be appreciated as I am completely at sea how to solve this.
Thank you.
I have Borland C++ Builder 5 installed, which includes tasm32 and tlink32.
The command-line options for TASM32 print as follows:
Turbo Assembler Version 5.3 Copyright (c) 1988, 2000 Inprise Corporation
Syntax: TASM [options] source [,object] [,listing] [,xref]
/a,/s Alphabetic or Source-code segment ordering
/c Generate cross-reference in listing
/dSYM[=VAL] Define symbol SYM = 0, or = value VAL
/e,/r Emulated or Real floating-point instructions
/h,/? Display this help screen
/iPATH Search PATH for include files
/jCMD Jam in an assembler directive CMD (eg. /jIDEAL)
/kh# Hash table capacity # symbols
/l,/la Generate listing: l=normal listing, la=expanded listing
/ml,/mx,/mu Case sensitivity on symbols: ml=all, mx=globals, mu=none
/mv# Set maximum valid length for symbols
/m# Allow # multiple passes to resolve forward references
/n Suppress symbol tables in listing
/os,/o,/op,/oi Object code: standard, standard w/overlays, Phar Lap, IBM
/p Check for code segment overrides in protected mode
/q Suppress OBJ records not needed for linking
/t Suppress messages if successful assembly
/uxxxx Set version emulation, version xxxx
/w0,/w1,/w2 Set warning level: w0=none, w1=w2=warnings on
/w-xxx,/w+xxx Disable (-) or enable (+) warning xxx
/x Include false conditionals in listing
/z Display source line with error message
/zi,/zd,/zn Debug info: zi=full, zd=line numbers only, zn=none
The command-line options for TLINK32 print as follows:
Turbo Link Version 2.5.0.0 Copyright (c) 1993,1998 Borland International
Syntax: TLINK32 objfiles, exefile, mapfile, libfiles, deffile, resfiles
#xxxx indicates use response file xxxx
-m Map file with publics -x No map
-s Detailed segment map -L Specify library search paths
-M Map with mangled names -j Specify object search paths
-c Case sensitive link -v Full symbolic debug information
-Enn Max number of errors -n No default libraries
-P- Disable code packing -H:xxxx Specify app heap reserve size
-OS Do smart linking
-B:xxxx Specify image base addr -Hc:xxxx Specify app heap commit size
-wxxx Warning control -S:xxxx Specify app stack reserve size
-Txx Specify output file type -Sc:xxxx Specify app stack commit size
-Tpx PE image -Af:nnnn Specify file alignment
(x: e=EXE, d=DLL) -Ao:nnnn Specify object alignment
-ax Specify application type -o Import by ordinals
-ap Windowing Compatible -Vd.d Specify Windows version
-aa Uses Windowing API -r Verbose link
So your linker command line
TLINK32 -Tpe -aa -x filename.obj,,,"kernel32.lib"
has the following options: -Tpe means output file type PE exe,
-aa means application type "uses Windowing API",
-x means no map.
Since the -n option was not specified, the default runtime libraries will be included.
Then there are six lists of filenames. The lists are separated by commas. The filenames are separated by spaces if I remember correctly.
Currently you have objfiles = filename.obj, resfiles=kernel32.lib, and the other four lists of filenames are empty. I think you actually mean kernel32.lib to be in the list of libfiles. Try this:
TLINK32 -Tpe -aa -x filename.obj, , , kernel32.lib, ,
This project will be easier to build and maintain if you create a makefile, because all it takes is one extra comma to make the linker stage fail. You've already experienced the frustration of trying to debug a mysterious build recipie.
# makefile for Borland make
# *** not tested yet! no source code.
# Not compatible with nmake.
# May be compatible with gnu make.
#
# Borland Turbo Assembler
$(TASM32)=TASM32.exe
$(TASM32FLAGS)=/m29A /ml
#
# Borland Turbo Link
$(TLINK32)=TLINK32.exe
$(TLINK32FLAGS)=-Tpe -aa -x
#
# objfiles
$(OBJ)=filename.obj
#
# exefile
$(BIN)=filename.exe
#
# mapfile
$(MAP)=
#
# libfiles
$(LIBS)=kernel32.lib
#
# deffile
$(DEF)=
#
# resfiles
$(RES)=
all: all-before $(BIN) all-after
$(BIN): filename.asm
# Turbo Assembler Version 5.3 Copyright (c) 1988, 2000 Inprise Corporation
# Syntax: TASM [options] source [,object] [,listing] [,xref]
.asm.o:
$(TASM32) $(TASM32FLAGS) $<
# Turbo Link Version 2.5.0.0 Copyright (c) 1993,1998 Borland International
# Syntax: TLINK32 objfiles, exefile, mapfile, libfiles, deffile, resfiles
# Note the commas separate the lists of filenames, not the filenames themselves
$(BIN): $(OBJ)
$(TLINK32) $(TLINK32FLAGS) $(OBJ), $(BIN), $(MAP), $(LIBS), $(DEF), $(RES)
Sorry this is about as far as I can get with this question, there's not much here that I can actually test. Hopefully this is enough to get your build on the right track. Good luck!

Installing Notepad++ C compiler plugin: linintl-8.dll is missing

Following the instructions on http://iitdu.forumsmotion.com/t108-gcc-compiler-in-notepad
However, upon execution of NPPExec with the code provided (below), ld.exe displays a warning detailing that linintl-8.dll is missing.
// The script code, C source code compiling with GNU CC (GCC) in notepad++ (by "NppExec" plug-in) and compressing with UPX...
//
// Enable? "//" signs remove in code line.
// Sample: C:\Program Files\CodeBlocks\MinGW\bin\gcc.exe "$(FULL_CURRENT_PATH)" -o $(NAME_PART)
YOUR_GCC\BIN\_PATH_HERE\gcc.exe "$(FULL_CURRENT_PATH)" -o $(NAME_PART)
// UPX Compress (with "--best, --ultra-brute" options)
// Enable? "//" signs remove in code line.
// Sample: C:\WINDOWS\system32\upx.exe --best --ultra-brute $(NAME_PART).exe
YOUR_UPX_PATH_HERE\upx.exe --best --ultra-brute $(NAME_PART).exe
Yet, I can see linintl-8.dll sitting in the bin directory of mingw.
Does anybody have any idea how this issue can be resolved, or alternatively an entirely different method to successfully compile C in notepad++ ?
I'm no Windows expert, but I know that dlls should go somewhere in C:/System or C:/System32 for Windows 7 you should check this question:
How do I register a DLL file on Windows 7 64-bit?

Resources