How do I go about linking in an asm .obj file from a .c file (don't really want to create a lib/dll).
I still need to have the
start:
end start
labels?
How do I get it so that the C main() function is the entrypoint...?
I still need to have the
start:
end start
labels?
How do I get it so that the C main() function is the entrypoint...?
You can't link an OBJ to a C file. When you compile the C files, they end up being OBJ files. When you compile the ASM files, they end up being OBJ files. Then you use the linker to combine all of the OBJs. You may have to make sure that the segment declarations you use in your ASM is compatible with your C compiler.
Not only don't you have to make an entry point in your ASM OBJ, but you _must_ not. You have to make sure that only one of your OBJs has an entry point defined.
Note that VC .net has some bug in it that crashes the linker when you try to link with an OMF. You need to turn the OBJ into a LIB first in this case (but your makefile can be set up to make this happen automatically).
If you want to use ASM routines from C, you still have to make a .H file that declares your ASM stuff and include that .H file from the C. You also have to make sure that you specify a calling convention for the function declarations in the .H file and follow that calling convention in your definitions of the functions. Remember that each calling convention decorates the symbol names differently.
If you want to use C from ASM, it's a similar (but reverse) procedure. Make some .ASH file (ASM header) for the C code that declares the symbols that the C provides as EXTRN, and include that ASH before making calls to the functions.
Not only don't you have to make an entry point in your ASM OBJ, but you _must_ not. You have to make sure that only one of your OBJs has an entry point defined.
Note that VC .net has some bug in it that crashes the linker when you try to link with an OMF. You need to turn the OBJ into a LIB first in this case (but your makefile can be set up to make this happen automatically).
If you want to use ASM routines from C, you still have to make a .H file that declares your ASM stuff and include that .H file from the C. You also have to make sure that you specify a calling convention for the function declarations in the .H file and follow that calling convention in your definitions of the functions. Remember that each calling convention decorates the symbol names differently.
If you want to use C from ASM, it's a similar (but reverse) procedure. Make some .ASH file (ASM header) for the C code that declares the symbols that the C provides as EXTRN, and include that ASH before making calls to the functions.
yessopotamus,
Note that VC .net has some bug in it that crashes the linker when you try to link with an OMF. You need to turn the OBJ into a LIB first in this case (but your makefile can be set up to make this happen automatically).
Have you tried to convert OMF object files to COFF with the following?
I coded a simple Omf2coff tool using this method.
Note that VC .net has some bug in it that crashes the linker when you try to link with an OMF. You need to turn the OBJ into a LIB first in this case (but your makefile can be set up to make this happen automatically).
Have you tried to convert OMF object files to COFF with the following?
link -edit objfilename.obj
I coded a simple Omf2coff tool using this method.
I know how to declare the symbols and reference them as extern statements and then compile both to obj files and link them to a single exe. That works so long as I have in the asm file
.data
.code
start:
procedure
end start
if I take away the start: end start part then I get,
"error A2088: END directive required at end of file"
it looks like the solution was just to put an END at the end of file
(what threw me off was the linker still gave:
"error LNK2001: unresolved external symbol _mainCRTStartup"
because my .bat file I used to compile both assembled and linked the asm part. A valid .obj is actually produced though which links correctly against the C .obj file.
.data
.code
start:
procedure
end start
if I take away the start: end start part then I get,
"error A2088: END directive required at end of file"
it looks like the solution was just to put an END at the end of file
(what threw me off was the linker still gave:
"error LNK2001: unresolved external symbol _mainCRTStartup"
because my .bat file I used to compile both assembled and linked the asm part. A valid .obj is actually produced though which links correctly against the C .obj file.
The start: label tells where the entrypoint will be, so there must be an entrypoint !!
The "end start" directive tells what the start: label will be called !!
This means you can change the "start" label if you like, as long as it matches in the "end .." directive.
Are you trying to compile an object with no default entrypoint?
The "end start" directive tells what the start: label will be called !!
This means you can change the "start" label if you like, as long as it matches in the "end .." directive.
Are you trying to compile an object with no default entrypoint?
not sure but my 2c:
means that a .LIB is missing, but from the missing function i can't easly see what file. Took a look in MSDN; Evil2kHomer is right.
error LNK2001: unresolved external symbol _mainCRTStartup
means that a .LIB is missing, but from the missing function i can't easly see what file. Took a look in MSDN; Evil2kHomer is right.
no. if you even change start: to something like my_label: it still uses that as the entry_point even if the main() procedure is there in the C program. You need to not use an entrypoint label but just the keyword end at the end of the asm file.
Vortex,
I don't run vc .net (since I don't use windows xp) so I can't test it out. Well as far as I remember, the vc .net link.exe always claimed to be converting my OMF to COFF. But then it would just crash. So I bypassed that bug by using the "lib" utility on the objs first. I guess I'll try that technique out next time... it seems a bit more convenient than making a .lib file.
I don't run vc .net (since I don't use windows xp) so I can't test it out. Well as far as I remember, the vc .net link.exe always claimed to be converting my OMF to COFF. But then it would just crash. So I bypassed that bug by using the "lib" utility on the objs first. I guess I'll try that technique out next time... it seems a bit more convenient than making a .lib file.
I'll just paste the entire process for anyone looking to do the same thing (link C & asm .obj files together in order to call an asm routine from C and not bother creating a .dll or library file):
--- fileasm.asm ---
.686
.model flat,stdcall
option casemap:none
public routine
routine proto C :dword ; one parameter
.data
;...
.code
option prologue:none ; don't use frame pointer
option epilogue:none ;
routine proc C arg1:dword
mov eax, ; arg1
ret ; C calling convention - the C call routine(arg1); will clean up the stack
routine ends
end
--- end fileasm.asm ---
--- file.c ---
#include <stdio.h>
extern void routine(int arg1); // would be extern "C" { void routine(int arg1); for a .cpp file
int main(int argc, char* argv[]) { routine(1); return 0; }
--- end file.c ---
--- make.bat ---
PATH=%PATH%;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin
\masm32\bin\ml /c /coff fileasm.asm
cl -I"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include" -I"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include" /Ox /Og /Ob2 /Oi /Ot /Oy /G7 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /EHsc /ML /GS /W3 /c /Wp64 /Zi /TP file.c
link /LIBPATH:"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib" /LIBPATH:"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib" /INCREMENTAL:NO /NOLOGO /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /MACHINE:X86 kernel32.lib file.obj fileasm.obj
--- end make.bat ---
--- fileasm.asm ---
.686
.model flat,stdcall
option casemap:none
public routine
routine proto C :dword ; one parameter
.data
;...
.code
option prologue:none ; don't use frame pointer
option epilogue:none ;
routine proc C arg1:dword
mov eax, ; arg1
ret ; C calling convention - the C call routine(arg1); will clean up the stack
routine ends
end
--- end fileasm.asm ---
--- file.c ---
#include <stdio.h>
extern void routine(int arg1); // would be extern "C" { void routine(int arg1); for a .cpp file
int main(int argc, char* argv[]) { routine(1); return 0; }
--- end file.c ---
--- make.bat ---
PATH=%PATH%;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin
\masm32\bin\ml /c /coff fileasm.asm
cl -I"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include" -I"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include" /Ox /Og /Ob2 /Oi /Ot /Oy /G7 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /EHsc /ML /GS /W3 /c /Wp64 /Zi /TP file.c
link /LIBPATH:"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib" /LIBPATH:"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib" /INCREMENTAL:NO /NOLOGO /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /MACHINE:X86 kernel32.lib file.obj fileasm.obj
--- end make.bat ---
yessopotamus,
You can use the linker coming with the Masm32 package, it does the Omf2coff conversion without problem.
You can use the linker coming with the Masm32 package, it does the Omf2coff conversion without problem.