The MASM Forum

Specialised Projects => Compiler Based Assembler => Assembler With Microsoft Visual C => Topic started by: jj2007 on June 25, 2012, 06:23:52 PM

Title: Noob problems
Post by: jj2007 on June 25, 2012, 06:23:52 PM
I am trying to use Masm in a C proggie but I can't convince the C proggie to use its main function.

Code: [Select]
include \masm32\include\masm32rt.inc

MasmProggie PROTO C :SDWORD, :SDWORD ; exports euclid to C

.code
MasmProggie proc C x:SDWORD, y:SDWORD
  print "This is assembler", 13, 10
  mov eax, x
  mul y
  ret ; return value already in eax
MasmProggie endp
end MasmProggie

Code: [Select]
#include <stdio.h>
#include <stdlib.h>

int MasmProggie(int, int);

int main(int argc, char* argv[])
{
  int i=10; //just for fun
  printf("Arg count=%d\n", argc);
  printf("The product of argct and 10: %d\n", MasmProggie(i, argc));
  return 0;
}

Assembles, compiles and links just fine, the C code is inside the exe but I see only the assembler output, i.e. "This is assembler".

How do I instruct cl, ml and link what is the entry point??

commandlines:
"%ProgramFiles%\Microsoft Visual Studio 9.0\VC\bin\cl.exe" /Zl /Fa C_wants_Asm.obj C_calls_Asm.cpp
\masm32\bin\link C_wants_Asm.obj C_calls_Asm.obj /out:C2A.exe
echo LINKED ##
echo ----------------
c_calls_asm.exe 123 456 789 abc
echo ----------------
Title: Re: Noob problems
Post by: sinsi on June 25, 2012, 06:39:37 PM
Know nothing about C but my .obj source always ended with just 'end', not 'end MasmProggie' like yours since that tells a linker where the start code is...
Title: Re: Noob problems
Post by: jcfuller on June 25, 2012, 07:56:47 PM
There was a download on the old board PipeSample.zip that I think created a lib to use for just this purpose?

James
Title: Re: Noob problems
Post by: jj2007 on June 25, 2012, 08:02:58 PM
@sinsi: error LNK2001: unresolved external symbol _mainCRTStartup
@James: sounds about right, will check.

Thanks to both :icon14:
Title: Re: Noob problems
Post by: sinsi on June 25, 2012, 08:24:19 PM
'link /entry:' maybe?
I remember a problem with link and that error, it had to do with making the entry point 'public' I think.
That was an asm proggie though.
Title: Re: Noob problems
Post by: dedndave on June 25, 2012, 09:43:13 PM
i suppose different C compilers are different, but...
i think the startup code happens, whether you ask for it or not - lol
then - it calls _main or _WinMain or whatever the compiler looks for, which is in the C program

i would think you could write the C program to call your code before anything else
but, the compiler startup code is likely to happen first, anyways
Title: Re: Noob problems
Post by: dedndave on June 26, 2012, 12:17:35 AM
oh yah...
the linker has a /ENTRY switch
but that won't "connect" your code to the C code
and - it appears that _WinMain is StdCall   :P
Title: Re: Noob problems
Post by: Ryan on June 26, 2012, 12:21:34 AM
Try
Code: [Select]
extern "C" int MasmProggie(int, int);
for your prototype in C++.  If you change the compiler to C by changing the extension to .c, you can omit the extern "C".

Also, per Sinsi's suggestion, take out the MasmProggie after end.

After that, I just used ml on the .asm file, followed by cl on the .cpp file, and then link with the .obj files.
Title: Re: Noob problems
Post by: jj2007 on June 26, 2012, 01:16:54 AM
Even with just a printf, the linker complains that it can't find libcmt.lib. So I set the path to the folder where it happens to sit, but no success. Either it can't find the lib, or it complains that oldnames.lib isn't there. Bloody hell, assembler is so simple compared to this utterly stupid "you have five nights to find out which option is good for your hello world proggie" game.

I'll change my nick to NoCforMe2 :icon_mrgreen:

LINK : fatal error LNK1181: cannot open input file 'libcmt.lib'
#include <stdio.h>

int main()
{
    printf ("hello world\n");
    return 0;
}
Title: Re: Noob problems
Post by: Ryan on June 26, 2012, 01:23:28 AM
Sounds like the environment variables might not be defined.

http://stackoverflow.com/questions/9356135/link-fatal-error-lnk-1104-cannot-open-file-libcmt-lib
Title: Re: Noob problems
Post by: Ryan on June 26, 2012, 01:25:05 AM
Which C environment are you using?

If you're using Express 2010, Visual Studio has its own command prompt.
Title: Re: Noob problems
Post by: dedndave on June 26, 2012, 01:26:36 AM
Jochen,
did you create a project in VS ?
if not, it may assume a bunch of things to be the default
for example, LIBCMT is for multi-threaded apps
and - if it can't find it, probably an environent var as Ryan said

start with a simple C program that compiles and runs - then modify it from there   :t
Title: Re: Noob problems
Post by: anta40 on June 26, 2012, 04:06:01 AM
I tried sinsi's suggestions, and it worked.

Here's how I do it:
1. First of all, I don't have VC installed. I use Win 7 SDK (http://www.microsoft.com/en-us/download/details.aspx?id=3138)
2. Invoke "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd /X86 /Release". This batch script will set the appropriate environment up, so you could easily compile from command line. Or you could also you the Windows SDK 7.1 Command Prompt.

3. Assemble the asm code
Code: [Select]
include \masm32\include\masm32rt.inc

MasmProggie PROTO C :SDWORD, :SDWORD ; exports euclid to C

.code
MasmProggie proc C x:SDWORD, y:SDWORD
  print "This is assembler", 13, 10
  mov eax, x
  mul y
  ret ; return value already in eax
MasmProggie endp
end
jwasm -c -coff c_wants_asm.asm

4. Compile the C code
cl /c c_calls_asm.c

5. Link them
link c_calls_asm.obj c_wants_asm.obj /out:ccc.exe

6. Run it, e.g: ccc aa bb "hello world" 123
Output:
Quote

ccc aa bb "hello world" 123
Arg count=5
This is assembler
The product of argct and 10: 50
Title: Re: Noob problems
Post by: Vortex on June 26, 2012, 04:11:57 AM
Hi jcfuller,

Here is the piping example. (http://www.masmforum.com/board/index.php?topic=18215.0)
Title: Re: Noob problems
Post by: jj2007 on June 26, 2012, 04:52:57 AM
Jochen,
did you create a project in VS ?
if not, it may assume a bunch of things to be the default
for example, LIBCMT is for multi-threaded apps
and - if it can't find it, probably an environent var as Ryan said

start with a simple C program that compiles and runs - then modify it from there   :t

Dave,

That was roughly my idea, too. In the meantime, I found an old example of mine, it runs fine, and it turns out that the solution is
#pragma comment( lib, "\\masm32\\SomeCode.lib" )
In very kind words: something like "pragma comment" is a dirty hack. I have seen and used quite a number of languages, but C/C++ is just a shame for the civilised programming world, honestly 8)

Anyway, thanks to everybody who tried to guide me through the C hell :biggrin:
Title: Re: Noob problems
Post by: MichaelW on June 26, 2012, 10:15:00 AM
The MASM32 components will conflict with the CRT so you cannot reasonably use masm32rt or the print macro.
Code: [Select]
;include \masm32\include\masm32rt.inc
.686
.model flat,stdcall

printf PROTO C :VARARG

;MasmProggie PROTO C :SDWORD, :SDWORD ; exports euclid to C
.data
    fmt db "This is assembler", 10, 0
.code
MasmProggie proc C x:SDWORD, y:SDWORD
  ;print "This is assembler", 13, 10
  invoke printf, ADDR fmt
  mov eax, x
  mul y
  ret ; return value already in eax
MasmProggie endp
end ;MasmProggie
Code: [Select]
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int MasmProggie(int, int);

int main(int argc, char* argv[])
{
  int i=10; //just for fun
  printf("Arg count=%d\n", argc);
  printf("The product of argct and 10: %d\n", MasmProggie(i, argc));
  getch();
  return 0;
}
Code: [Select]
set file1="MasmProggie"
set path=\masm32\bin;%PATH%
ml /c /coff %file1%.asm
pause
set file2="test"
set PATH=C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin;%PATH%
set INCLUDE=C:\Program Files\Microsoft SDK\include;C:\Program Files\Microsoft Visual C++ Toolkit 2003\include;%INCLUDE%
set LIB=C:\Program Files\Microsoft SDK\Lib;C:\Program Files\Microsoft Visual C++ Toolkit 2003\lib;%LIB%
cl /W4 /FA %file2%.c %file1%.obj
pause
Title: Re: Noob problems
Post by: KeepingRealBusy on June 26, 2012, 11:46:30 AM
JJ,

Why do you think we areall  here in the MASM32 forum?

Dave.
Title: Re: Noob problems
Post by: anta40 on June 26, 2012, 04:02:09 PM
but C/C++ is just a shame for the civilised programming world, honestly 8)

Blame AT&T / UNIX for them  :P
The reason I use C is because... it's heavily used in UNIX.
C++ is actually a somewhat better C, but it can be easily used to overcomplicate things.

For people who can't stand C/C++, Pascal might be a good choice :P
Title: Re: Noob problems
Post by: jj2007 on June 27, 2012, 03:29:37 AM
The MASM32 components will conflict with the CRT so you cannot reasonably use masm32rt or the print macro.

My C++ proggie calls successfully the Masm32 print macro, and uses equally successfully MasmBasic's Recall (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1165) function, a fairly complex routine using also Windows API calls. So that seems not to be a big obstacle. But, afaik print is not a crt routine, so you might have a point there...
What still bothers me is that I can do it from Visual C Express but not with cl.exe...

For people who can't stand C/C++, Pascal might be a good choice :P

MasmBasic (http://masmforum.com/~masm32/board/index.php?topic=94) is inspired by GfaBasic, which (in its successful moments) was considered the perfect synthesis of BASIC and Pascal. So I understand what I mean.
Title: Re: Noob problems
Post by: hutch-- on June 27, 2012, 01:31:44 PM
The 16 bit GFA I used back in about 1995 was a very good tool, the libraries were written in assembler and it ran like it. The scoping rules took a little getting used to but it was a very "can do" language way back then. It was "kick ass" to the C version 7 I was using which was a lemon and I wrote my last 16 bit code in GFA. Come 32 bit I went in the direction of PowerBASIC where I wanted a basic compiler but as a true addict, it was MASM that offered the promise of FLAT memory model that existed only in Microsoft documentation in earlier versions of MASM.

I think without FLAT memory model MASM I would have retired in about 1996 as I detested the old 16 bit fudges that made DOS and Win3? chug along and co-operative multitasking was something that everyone should experience at least once, the novelty wore off the second time. Anything else running could take down a perfectly written app if it did something naughty with memory, nothing like having your code section overwritten with another app's data.  :biggrin:
Title: Re: Noob problems
Post by: MichaelW on June 27, 2012, 02:33:07 PM
Traditionally, when mixing assembly language with a high-level language, because high-level languages generally require initialization code (to initialize the CRT, for example), you had to make the high-level language module the main module. Failing this, you had to find a way to force the high-level language initialization code to run from the assembly module. In my tests, using the Visual C++ Toolkit 2003 compiler and command lines that do not specify the entry point, the compiler seems to know that the C module must be the main module. So I can reverse the order of the files on the command line, or specify an entry point in the END statement in the assembly module, and the resulting app compiles and runs OK. With other compilers, or when compiling and linking in separate steps, it might not work the same way.
Title: Re: Noob problems
Post by: Vortex on June 28, 2012, 03:36:21 AM
Hi Jochen,

You can create C executables without depending on C run-time startup modules.
Title: Re: Noob problems
Post by: jj2007 on June 28, 2012, 04:51:43 AM
Hi Jochen,

You can create C executables without depending on C run-time startup modules.

Hi Erol,
Yes, by not using any output functions etc.
My problem is it works fine from VS Express but I'd like to start from my Masm IDE via the command line. In VS the *.cpp source has this command line:

/ZI /nologo /W3 /WX- /Od /Oy- /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /GS /arch:SSE /fp:precise /Zc:wchar_t /Zc:forScope /Yu"StdAfx.h" /Fp"Debug\JJC.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /analyze- /errorReport:queue

... which I find pretty disgusting but there are probably lots of "reasons" for this monster.
Title: Re: Noob problems
Post by: Vortex on June 28, 2012, 05:20:00 AM
Hi Jochen,

You can use output functions like printf without the default static C run-time library. msvcrt.dll is exporting output functions like printf

You can simplify the command-line parameters. For example, do you need all the UNICODE features?
Title: Re: Noob problems
Post by: Don57 on June 28, 2012, 05:22:30 AM
Years ago we use to create a section of dummy code in the higher level language, then have the higher level code call an assembler stub, which would then write the assembler code to the dummy code section. A real pain but usually worked as a last resort.
Title: Re: Noob problems
Post by: Ghandi on July 17, 2012, 12:57:24 PM
Quote
/NODEFAULTLIB:LIBCMT.LIB

Use this to tell the linker not to link against libcmt.lib and it will then force the linker to look amongst any object files/libs which you've provided.

Just as you can set which .lib files are used via the commandline rather than using '#pragma comment (lib, "libname.lib")', horses for courses really.

Make a function WinMain in your ASM code and only have 'END' at the end of your source code and link with any of the CRT lib files and you will automatically get the bootstrap code placed in your executable which will call WinMain. Or you can even make your own functions which fit the prototype and the linker will be quite happy to link to your version of printf instead of the one it would have gotten from libcmt.lib

Don't forget to give it the proper declaration so that params are accessible and you don't have to write a single line in C yet you can include lib files like zLib and they will actually be able to initialize the heap rather than crashing with an access violation. I had trouble using zLib with MASM after compiling it with VC6++ and i couldn't figure out what the problem was at first, used the NODEFAULTLIB switch and then replaced any of the functions it complained about and it worked. Now (if i can find it again) i have a 100% MASM32 compatible zLib.lib file that doesn't require any of the C runtime because any calls to malloc/free/memcpy/etc are replaced with either the Win32 API equivalent OR a handrolled ASM variant and there is now no dependency at all on the CRT library.

HR,
Ghandi