News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Noob problems

Started by jj2007, June 25, 2012, 06:23:52 PM

Previous topic - Next topic

jj2007

I am trying to use Masm in a C proggie but I can't convince the C proggie to use its main function.

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


#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 ----------------

sinsi

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...

jcfuller

There was a download on the old board PipeSample.zip that I think created a lib to use for just this purpose?

James

jj2007

@sinsi: error LNK2001: unresolved external symbol _mainCRTStartup
@James: sounds about right, will check.

Thanks to both :icon14:

sinsi

'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.

dedndave

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

dedndave

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

Ryan

#7
Try
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.

jj2007

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;
}

Ryan

Sounds like the environment variables might not be defined.

http://stackoverflow.com/questions/9356135/link-fatal-error-lnk-1104-cannot-open-file-libcmt-lib

Ryan

Which C environment are you using?

If you're using Express 2010, Visual Studio has its own command prompt.

dedndave

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

anta40

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
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
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

Vortex


jj2007

Quote from: 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

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: