Calling NASM procedure from gcc code

Programming, for all ages and all languages.
Post Reply
crackers

Calling NASM procedure from gcc code

Post by crackers »

I have problem with doing it
asm code

Code: Select all

[BITS 32]
[GLOBAL do_something]
[EXTERN _k_main]
call _k_main
hlt

do_something:
  mov eax, 4
  ret
c code

Code: Select all

extern void do_something(void);
void k_main()
{
  do_something();
}
I'm getting linker error - "undefined reference to '_do_something'".
So I've changed asm file by adding _ before both do_something but I'm still getting the same error. Anybody know what I'm doing wrong?
pkd

Re:Calling NASM procedure from gcc code

Post by pkd »

You need to use Name Mangling in your asm code.

for elf32/64 (LINUX not sure for windows)

name your function _Z12Do_Somethingv

Check your C/C++ executable with a Hex Editor to see the mangled name that it is trying to find

the _Z is standard
the number is how many chars in Name
the v stands for void (Parameter)
i for int
c for char
etc.


and call form c/c++

Code: Select all

   Do_Something(void);

Code: Select all

[Bits 32]
global _Z12Do_Somethingv

_Z12Do_Somethingv

...code here

  ret
Hope this helps if not google for name mangling

bye
pkd
zloba

Re:Calling NASM procedure from gcc code

Post by zloba »

try this

Code: Select all

extern "C" void do_something(void);
this tells the C++ compiler not to use mangling when looking for do_something
crackers

Re:Calling NASM procedure from gcc code

Post by crackers »

pkd wrote: You need to use Name Mangling in your asm code.

for elf32/64 (LINUX not sure for windows)

name your function _Z12Do_Somethingv

Check your C/C++ executable with a Hex Editor to see the mangled name that it is trying to find
Well I checked my compiled file (but not assembled) and I only see _do_something.

zloba wrote: try this

Code: Select all

extern "C" void do_something(void);
this tells the C++ compiler not to use mangling when looking for do_something
Well I'm using C compiler and when I try to do something like that I'm getting "syntax error before string constant". The funniest thing is that under linux it's working just fine. Only under windows (djgpp) I'm having such problems.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Calling NASM procedure from gcc code

Post by Solar »

Did you add the underscore both to the "GLOBAL" statement and the function label?

Code: Select all

[BITS 32]
[GLOBAL _do_something]
[EXTERN _k_main]
call _k_main
hlt

_do_something:
  mov eax, 4
  ret
To avoid the whole issue, use your original code, and force the C compiler not to use leading underscores: [tt]gcc -fno-leading-underscore ...[/tt]
Every good solution is obvious once you've found it.
crackers

Re:Calling NASM procedure from gcc code

Post by crackers »

Solar wrote: Did you add the underscore both to the "GLOBAL" statement and the function label?
Yes I did.
Solar wrote: To avoid the whole issue, use your original code, and force the C compiler not to use leading underscores: [tt]gcc -fno-leading-underscore ...[/tt]
I tried that too with no effect - getting "undefined reference to 'do_something'" >:(
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Calling NASM procedure from gcc code

Post by Solar »

Would you mind quoting the NASM command you use to assemble the object file, and the linker command you use to build the executable?

I've got this suspicion that either you don't have an object file coming out of NASM, or that you aren't giving that object file to the linker...
Every good solution is obvious once you've found it.
crackers

Re:Calling NASM procedure from gcc code

Post by crackers »

Code: Select all

nasm -f coff entry.asm -o entry.o
C:\djgpp\bin\gcc -fno-leading-underscore -c kernel.c -O2 -o kernel.o
C:\djgpp\bin\ld -Map kernel.map entry.o kernel.o -Tlink.ld -o kernel.bin
and linker script

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY("k_main")
SECTIONS {
 .text 0x10000 : {
  code = . ; _code = . ;
  *(.text)
 }
 .data : {
  *(.data)
 }
 .bss : {
  bss = . ; _bss = . ;
  *(.bss)
  *(.COMMON)
 }
 end = . ; _end = . ;
} 
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Calling NASM procedure from gcc code

Post by Solar »

Well, I don't have DJGPP at hand, and the Cygwin 'ld' chokes on the classic "PE operation on non-PE file".

But [tt]objdump -t entry.o[/tt] and [tt]objdump -t kernel.o[/tt] will show you the symbol tables of the object files. It turns out the Cygwin gcc at least is happily ignoring -fno-leading-underscores...
Every good solution is obvious once you've found it.
zloba

Re:Calling NASM procedure from gcc code

Post by zloba »

It turns out the Cygwin gcc at least is happily ignoring -fno-leading-underscores
-underscores or -underscore?

Code: Select all

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

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

Re:Calling NASM procedure from gcc code

Post by crackers »

After some time I've returned to this problem and discovered that I forgot to write

Code: Select all

section .text
in my asm code ;D
Post Reply