Linking assembler and c code with visual studio.

I am taking an Assembler class and the prof wants us to write a C program that calls an assembler routine.  I'm using Visual Studio v6 and need to know how to set the model size for for the C part.  Then I need to know how to link the .obj file that I created with MASM to it.  I tried the help disks, but the one I need is spent.  HELP!  
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

This is homework so we can't give you a working solution but may be some additional information
MSC normaly adds an _at beginning of a function name so inside your assembler module you should name the functon
than you can call it from C with
for linking both language have to use same model size so how to set C model size depends on how you set model size for masm.
to link them together add the obj file to the project
sdickensAuthor Commented:
I don't need help with the code.  My code will work just fine if I knew how to use Visual C++'s linker.  Once again, what I need to know is how to set the model size in visual c++ 6.0 and what the syntax for using Link on the command line is.  My CD is dead so I can't access the help files
I'm wondering if it's possible that MS no longer supports memory this possible?  I've looked at the help file on compiler options, and I couldn't find anything???
I also looked in the build options where that memory model switch use to be (I think in Visual C++ 4.0), and nothing there either.

I have the linker switches however:
(This is copied directly from the DevStudio 6.0 help)

sybtax: LINK [arguments]

/ALIGN:number Specifies the alignment of each section
/BASE:{address | @filename,key} Sets a base address for the program
/COMMENT:["]comment["] Inserts a comment string into header
/DEBUG Creates debugging information
/DEBUGTYPE:BOTH Creates particular formats of debugging information
/DEF:filename Passes a module-definition (.DEF) file to the linker
/DEFAULTLIB:library Searches specified library when resolving external references
/DELAY Controls the delayed loading of DLLs
/DELAYLOAD Causes the delayed loading of the specified DLL
/DLL Builds a DLL
/DRIVER[:UPONLY] Creates a Windows NT kernel mode driver
/ENTRY:function Sets the starting address
/EXETYPE:DYNAMIC Builds a virtual device driver
/EXPORT Exports a function
/FIXED[:NO] Creates a program that can be loaded only at its preferred base address
/FORCE[:{MULTIPLE|UNRESOLVED}] Forces link to complete in spite of unresolved or multiply defined symbols
/GPSIZE:# Specifies the size of communal variables for MIPS and Alpha platforms
/HEAP:reserve[,commit] Sets the size of the heap in bytes
/IMPLIB:filename Overrides the default import library name
/INCLUDE:symbol Forces symbol references
/INCREMENTAL:{YES|NO} Controls incremental linking
/LARGEADDRESSAWARE Tells the compiler that the application supports addresses larger than two gigabytes.
/LIBPATH:path Allows the user to override the environmental library path
/LINK50COMPAT Generates import libraries in Visual C++ Version 5.0 format
/MACHINE:{IX86|ALPHA|ARM|MIPS|MIPSR41XX|PPC|SH3|SH4} Specifies the target platform
/MAP Creates a map file  
/MAPINFO:{EXPORTS|FIXUPS|LINES} Includes the specified information in the map file
/MERGE:from=to Combines sections
/NODEFAULTLIB[:library] Ignores all (or specified) default libraries when resolving external references
/NOENTRY Creates a resource-only DLL
/NOLOGO Suppresses startup banner
/OPT:{REF|NOREF|ICF[,iterations]|NOICF} Controls LINK optimizations
/ORDER:@filename Places COMDATs into the image in a predetermined order
/OUT:filename Specifies the output file name
/PDB:filename Creates a program database (.PDB) file
/PDBTYPE:{con[solidate]|sept[ypes]} Specifies where to store the Program Database (PDB) debug type information.
/PROFILE Enables profiling (creates a mapfile)
/RELEASE Sets the checksum in the .EXE header
/SECTION:name,attributes Overrides the attributes of a section
/STACK:reserve[,commit] Sets the size of the stack in bytes
/STUB:filename Attaches an MS-DOS stub program to a Win32 program
/SUBSYSTEM:{CONSOLE|WINDOWS|NATIVE|POSIX|WINDOWSCE} [,major[.minor] ] Tells the operating system how to run the .EXE file
/SWAPRUN:{NET|CD} Tells the operating system to copy the linker output to a swap file before running it
/VERBOSE[:LIB] Prints linker progress messages
/VERSION:major[.minor] Assigns a version number
/VXD Creates a virtual device driver (VxD)
/WARN[:level] Specifies warning level
/WS:AGGRESSIVE Aggressively trim process memory
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

sdickensAuthor Commented:
This is what I have:
convertC.obj (C object file created w/Visual C++6)
convertA.obj (Assembler object file created with MASM 6.11)
When I do the following:

LINK convertC.obj convertA.obj conv.exe

I get this error message
"LINK : Error :Segment reference in fixup record.

convertA.obj : Fatal error LNK1123: failure dring conversion to COFF file invalid or corupt"

I think it has something to do with the memory model size.  I wrote my assembler code to use a small memory model.  
I tried using code that was given in class and compiled with turbo C and it doesn't work either. If only I had held on to Turbo!  HELP
I think you must set FLAT memory model in your asm code.
>My CD is dead

sdickensAuthor Commented:
Rusne I tried settig the model to flat, but MASM doesn't recognize it.  Any other ideas?
Make Your project nd include in him You asm code source. Use You __asm keyword to define Your assembler code. Set memory mmodel on Your all project that what You want but already for all Your sources. And build project. Wiht VC 6.x You need not more.
sdickensAuthor Commented:
pig, the prof wants two separate files.  Your answer may work, but I can't use it.
Post you Assembler function!

it should look somewhat like the following!

_TEXT   segment byte public 'CODE'
            assume  cs:_TEXT   ;; Add these 2 lines

            PUBLIC  _AsmFunc

_AsmFunc    proc    near
                    push    bp                  ;
                    mov     bp,sp               ;
;   Your code goes here
                   pop     bp                  ;
_AsmFunc    endp

_TEXT       ends       ;; Add this line too


I use TASM but the fixup error in my case was because [_TEXT] was not defined..the linker is unable to resolve which segment you are refering too!

sdickensAuthor Commented:
pig, the prof wants two separate files.  Your answer may work, but I can't use it.
sdickensAuthor Commented:
I'm at work now so I don't have the code but the structure of it is the same as what sergelebel posted.  The prof gave us a sample program that calls a assembler routine from C so I know that the problem is not in the code, but rather something to do with the way VC++ compiles.  
Just a suggestion!   add your OBJ to a
library and add this library on the Link command line instead of specifying it
like .. Link c.obj+asm.obj

might sound strange..but this worked for me!
Check this out...

as far as the model goes, you could try the following two...

..model FLAT, C

the second one MUSt work, but it's a good idea to try both ;)

I dunno why the two dots appeared.. it should be a single one... (that is before the model)...

als, to put link the ASM with your C code, what you should do is this...

compile the ASM and it will create an object file (OBJ).. then you add that object file to your C project and compile. that will do it...

sdickensAuthor Commented:
I already said that the assembler code was written for a small model.  I don't want to change it.  I need to know how to set it in Visual C++ not in assambler.  Besides, I alread tried flat and it won't compile.  
Just a suggestion: make sure you prototype your assembler function in your C++ code like this:

extern "C" void assemblyfunc();

The 'extern "C"' stops the name mangling that a C++ compiler will usually perform.

I am afraid you cannot link a small model ASM with Visual C++ code, since Visual C++ always uses the flat model. You have yo modify the assembly model or use a C++ compiler which supports DOS applications.
First of all, emild is right... the only VC compiler that you can use to link a SMALL model ASM object file is VC 1.x... VC 1.52 works for sure... SMALL model is for programs that are 64k in size which is a single segment, and that's not the way windows works.... it uses FLAT model memory and uses sectors which works in a whole different way than segments... anyways, you should probably find a different compiler if you'd like to create DOS programs using the small model.. TC++, Borland C++ would all work out for you great...

And finally, I don't know if you read the tutorial that i mentioned, but you better read, since it uses small model exactly as you want it...


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sdickens is using Microsoft not Borland.

viktornet means selectors not sectors I believe.

I believe there is a way to accomplish what sdickens wants.
yeah, i meant selectors and not sectors... sorry...
it's possible but very difficult... the easiest way would be to use FLAT model if you're compiling with MSVC and use SMALL model if you're compiling with a DOS compiler...

Are you sure do you set correct linker's
options? Especially libraries option.
If you are working in 32bit mode, only FLAT memory model works in both C & ASM.
When compilling, look that the code is created for the same processor in both
C and ASM.
sdickensAuthor Commented:
I'm at work now so I don't have the code but the structure of it is the same as what sergelebel posted.  The prof gave us a sample program that calls a assembler routine from C so I know that the problem is not in the code, but rather something to do with the way VC++ compiles.  
sdickensAuthor Commented:
I ended up downloading an old version of Turbo C and it worked fine.  Apparently MASM doesn't recognize the flat memory model so it was my only option.  Thanks everyone for your help!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.