[ACCEPTED]-Adding leading underscores to assembly symbols with GCC on Win32?-mingw

Accepted answer
Score: 32

One option, though dangerous, is to convince 43 GCC to omit the ABI-required leading underscore.

  • -fleading-underscore

    This 42 option and its counterpart, -fno-leading-underscore, forcibly change 41 the way C symbols are represented in the 40 object file. One use is to help link with 39 legacy assembly code.

    Warning: the -fleading-underscore switch causes 38 GCC to generate code that is not binary 37 compatible with code generated without that 36 switch. Use it to conform to a non-default 35 application binary interface. Not all targets 34 provide complete support for this switch.

Another, safer 33 option, is to explicitly tell GCC the name 32 to use.

5.39 Controlling Names Used in Assembler Code

You can specify the name to be used 31 in the assembler code for a C function or 30 variable by writing the asm (or __asm__) keyword after 29 the declarator as follows:

     int foo asm ("myfoo") = 2;

This specifies 28 that the name to be used for the variable 27 foo in the assembler code should be ``myfoo' rather than the usual \``_foo'.

On 26 systems where an underscore is normally 25 prepended to the name of a C function or 24 variable, this feature allows you to define 23 names for the linker that do not start with 22 an underscore.

It does not make sense to 21 use this feature with a non-static local 20 variable since such variables do not have 19 assembler names. If you are trying to put 18 the variable in a particular register, see 17 Explicit Reg Vars. GCC presently accepts such code with 16 a warning, but will probably be changed 15 to issue an error, rather than a warning, in 14 the future.

You cannot use asm in this way in 13 a function definition; but you can get the same effect 12 by writing a declaration for the function 11 before its definition and putting asm there, like 10 this:

 extern func () asm ("FUNC");

 func (x, y)
      int x, y;
 /* ... */

It is up to you to make sure that the 9 assembler names you choose do not conflict 8 with any other assembler symbols. Also, you 7 must not use a register name; that would 6 produce completely invalid assembler code. GCC 5 does not as yet have the ability to store 4 static variables in registers. Perhaps 3 that will be added.

In your case,

extern int bar(int x) asm("bar");

should tell 2 GCC that "bar uses asm name ``bar`', even 1 though it's a ccall function".

Score: 9

You can use the C preprocessor to preprocess 10 your assembly and use a macro to add the 9 missing underscores on Windows. First, you 8 need to rename your assembly file from bar.s 7 to bar.S (capital 'S'). This tells gcc to 6 use cpp to preprocess the file.

To add the 5 missing underscores, you can define a macro 4 "cdecl" like this:

#if defined(__WIN32__)
# define cdecl(s) _##s
# define cdecl(s) s

Then use it like this:

.global cdecl(bar)
    movl 4(%esp), %eax
    addl %eax, %eax

Note 3 that Mac OSX also requires leading underscores, so 2 you can update the first line of the macro 1 like this:

#if defined(__WIN32__) || defined(__APPLE__)
Score: 5

can you declare it twice?

.global bar
.global _bar

I haven't written 2 assembly in awhile, but does the .global 1 identifier just act sort of like a label?

Score: 4

Compilers for the ELF target do not add 3 leading underscores by default. You could 2 add -fleading-underscore when compiling to ELF format (under 1 Linux). Use a conditional in the makefile.

Reference: http://opencores.org/openrisc,gnu_toolchain (do an on-page search for "leave global names unchanged")

Score: 0

Had this issue with JNI, where e.g. the 7 Java Runtime 1.5/32Bit expects leading underscores 6 for extern-C functions. "-fleading-underscore" does 5 not do the job!

Solution here was to parse 4 the stub-headers from the Java-Compiler 3 for declared functions and derive substitution 2 defines for these with pattern ´#define 1 bar _bar´ .

More Related questions