Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ошибки сборки при смешивании C и ASM
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
smalcom
Доброго дня.
Столкнулся с "невероятной" проблемой.
Есть файлы

main.c
Код
#include "asm_foo.h"

int main()
{
    asm_foo();
    return 0;;
}


asm_foo.h
Код
void asm_foo(void);


asm_foo.S
Код
#include <avr/io.h>
.section .text
.global asm_foo
asm__foo:
    ret


Сборка и результат
Цитата
asmc>avr-gcc -mmcu=atmega8 -o test_asm asm_foo.S main.c

C:\DOCUME~1\smalcom\LOCALS~1\Temp\cctCUv75.o: In function `main':
main.c:(.text+0x8): undefined reference to `asm_foo'
collect2.exe: error: ld returned 1 exit status


Буква S в расширении файла большая. ОС: WinXP 64

Компилятор
Цитата
asmc>avr-gcc -v
Using built-in specs.
COLLECT_GCC=G:\opt\avrgcc\bin\avr-gcc.EXE
COLLECT_LTO_WRAPPER=g:/opt/avrgcc/bin/../libexec/gcc/avr/4.7.2/lto-wrapper.exe
Target: avr
Configured with: ../gcc-4.7.2/configure --prefix=/g/opt/avrgcc --target=avr --with-dwarf2 --enable-languages=c,c++ --disable-libssp --disable-nls
Thread model: single
gcc version 4.7.2 (GCC)


На форуме искал, в интернете искал. У всех с такой ошибкой обычно была маленькая буква s в расширении.
Можно предположить, что проблема в неверном понимании этой буквы виндой или чем-то ещё, но тогда, по идее, была бы ошибка компиляции из-за использования #include в ассемблерном листинге.
---
Попробовал на другом ПК под линуксом и не авр-гцц, а обычный
Цитата
[smalcom@servelat asmc]$ gcc -o test_asm asm_foo.S main.c
/tmp/ccj533Bl.o: у функції «main»:
main.c:(.text+0x5): невизначене посилання «asm_foo»
collect2: error: ld returned 1 exit status

[smalcom@servelat asmc]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/src/gcc-4.7.2/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --enable-libstdcxx-time --enable-gnu-unique-object --enable-linker-build-id --with-ppl --enable-cloog-backend=isl --disable-ppl-version-check --disable-cloog-version-check --enable-lto --enable-gold --enable-ld=default --enable-plugin --with-plugin-ld=ld.gold --with-linker-hash-style=gnu --disable-multilib --disable-libssp --disable-build-with-cxx --disable-build-poststage1-with-cxx --enable-checking=release
Thread model: posix
gcc version 4.7.2 (GCC)

результат тот же. Значит есть какойто нюанс. Никак не могу понять какой.
ReAl
Цитата(smalcom @ Feb 8 2013, 16:05) *
asm_foo.S
Код
#include <avr/io.h>
.section .text
.global asm_foo
asm__foo:
    ret
Это тут опечатка или и в коде два подчерка в метке asm__foo: ?
smalcom
мдеееееее.
спасибо, мил человек.
проблема решена.

Наткнулся на новую проблему, опять по невнимательности. Вдруг ктото столкнётся.
Если у вас не main.c, а main.cpp, соответственно запустится "плюсовый" компилер - g++, то опять пойдут ошибки "undefined reference".
Чтобы этого не было, объявления ассемблерных функций - в данном примере это
Код
void asm_foo(void);


надо правильно экспортировать,

Код
extern "C"
{
void asm_foo(void);
}

ReAl
Для одной функции можно и
Код
extern "C" void asm_foo(void);

Но лучше сразу так:
Код
#ifdef __cplusplus
extern "C" {
#endif
    // всё равно рано или поздно их будет много, пусть одним блоком
    void asm_foo(void);

#ifdef __cplusplus
}
#endif
и тогда .h можно будет включать хоть в .c, хоть в .cpp
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.