I am attempting to call an assembly function from C++, and the linker is saying that the function I am trying to call does not exist. Here is the error:
avr-gcc -mmcu=atmega328 -Wall -o main.elf hello.S main.cpp
/tmp/ccS7uaAX.o: In function `main':
main.cpp:(.text+0x14): undefined reference to `hello(char, char, char, char, char)'
collect2: error: ld returned 1 exit status
//Somewhere in hello.S
extern void hello(char, char, char, char, char);
hello(1, 2, 3, 4, 5);
0: 0f 93 push r16
2: cf 93 push r28
4: df 93 push r29
6: cd b7 in r28, 0x3d ; 61
8: de b7 in r29, 0x3e ; 62
a: 05 e0 ldi r16, 0x05 ; 5
c: 24 e0 ldi r18, 0x04 ; 4
e: 43 e0 ldi r20, 0x03 ; 3
10: 62 e0 ldi r22, 0x02 ; 2
12: 81 e0 ldi r24, 0x01 ; 1
14: 0e 94 00 00 call 0 ; 0x0 <main>
18: 80 e0 ldi r24, 0x00 ; 0
1a: 90 e0 ldi r25, 0x00 ; 0
1c: df 91 pop r29
1e: cf 91 pop r28
20: 0f 91 pop r16
22: 08 95 ret
0: 08 95 ret
Try this: in main.cpp,
extern "C" void hello(char, char, char, char, char);
"C" in it. C++ changes the name of the function to include its type, which is called name mangling. The "C" tells the compiler not to mangle. The assembler doesn't mangle, so the compiler needs to know not to.
Incidentally, the mangling is how the linker is able to tell you the parameter types of the
hello it is looking for.
strings main.o |grep hello on your current object file and you will see a reference to hello with all sorts of funny characters after it. That is the mangled name.