NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: trismarck on June 04, 2012, 05:01:08 PM
-
Here is a VS project that fails to compile and I don't know why. The project looks like this:
(http://i.imgur.com/LxIZR.jpg)
sum.cpp
// sum.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
extern "C" int sumX(void);
int main()
{
std::cout << sumX() << "\n" ;
return 0;
}
sum.asm
section .text ;
global _sumX ;
_sumX:
mov eax,7
ret
Why does that fail to compile? It looks like the linker somehow fails to add the _sumX() function to the project, but I don't know if this is the case / why it happens.
The error:
(http://i.imgur.com/Xlxli.jpg)
//update:
- changing the name of the sum.cpp file - new errors*
- changing the name of the sum.obj file - the program compiles
The errors:
(http://i.imgur.com/02NE1.jpg)
Could it be that both sum.cpp and sum.asm compiled to sum.obj and this prevents the linker from properly linking the functions? (if this is the case, then why when changing .cpp file name doesn't solve the issue)
-
As it was 7 yrs ago, I don't remember exactly how I solved that problem, but I seem to think undercoating _sum or decorating your declaration extern "C" int _sum(void) might solve the problem. Have a look in kernel32.inc and see how it's done there.
-
Hmm, what do you mean by "undercoating"? (I couldn't find the word in the dictionary)
After adding the underscore in various places in the code, VS still yields an error.
Also, I don't know if I'm looking on the right kernel32.inc file (I don't know what the file contains actually) (the kernel32.inc file from MASM?), but if I do, it fails to give me any clues on how the proper syntax should be. Here is how the file looks inside:
OpenSemaphoreA PROTO STDCALL :DWORD,:DWORD,:DWORD
IFNDEF __UNICODE__
OpenSemaphore equ <OpenSemaphoreA>
ENDIF
OpenSemaphoreW PROTO STDCALL :DWORD,:DWORD,:DWORD
IFDEF __UNICODE__
OpenSemaphore equ <OpenSemaphoreW>
ENDIF
OpenThread PROTO STDCALL :DWORD,:DWORD,:DWORD
OpenWaitableTimerA PROTO STDCALL :DWORD,:DWORD,:DWORD
IFNDEF __UNICODE__
OpenWaitableTimer equ <OpenWaitableTimerA>
ENDIF
OpenWaitableTimerW PROTO STDCALL :DWORD,:DWORD,:DWORD
IFDEF __UNICODE__
OpenWaitableTimer equ <OpenWaitableTimerW>
ENDIF
//edit:
This is definitely a linker issue. When I change the name of either of the files (sum.cpp or sum.asm), then inside "c:\Documents and Settings\ddd\My Documents\Visual Studio 2008\Projects\20120604\sum\sum\Debug\sum.obj" directory, two *.obj files are created (sum.obj and sum1.obj). So if those two files (sum.cpp and sum.asm) have the same name, the linker creates two *.obj files with the same name. Hence the error. The workaround is to remember to name the *.asm uniquely within the VS project files (uniquely == no file in VS project can have the same filename as the *.asm file).
Also, I don't know why, but now changing the name of _either_ file (instead of only changing the *.asm file name) compiles the project correctly.
The other thing I've thought about is that maybe VS has a built-in sum() function and this sum() function somehow interferes with the file of the same name. But this is probably not the case.
-
Sorry, spell-check, it should have been undecorated.
Absolutely, it is a linker issue, but beyond this I'm not much help to you as I don't have a M$ box anymore. I know I have some mixed language projects in VS6, but without an operational operating system, I have no way of seeing what the settings where and I'm not even sure if I remember where the backups are.
-
sum.cpp gets compiled to sum.obj
sum.asm gets assembled to sum.obj
Do you see the problem here? ;)
-
Yes, but why does it happen? ;D
Shouldn't the compiler / the linker 'handle' a situation like this? (as those are files use two different programming languages).
-
The .obj file format is the intermediate format representing code that has been compiled/assembled into OBJect ( or native ) form. Each tool ( the C++ compiler as well as the Nasm assembler ) is responsible for converting your source code into this binary representation. For executables built on Windows the stardard file extension is .obj. Thus each tool is creating a file named sum.obj to contain the respective conversion, thus overwriting the other!
As a general rule ( ie: 99.999% of the time ) never attempt to build a program that contains multiple versions of files that have the same name but differ in file extension only ( ie: sum.ccp, sum.asm ). There can be times when you will have projects that do this but the makefile rules must be modified to handle this situation ( usually with environment variables or command line switches ).
In your case, however, simply change the name of one of the files ( leaving the extension alone ) and you'll be fine.