【问题标题】:undefined symbols in .o file.o 文件中未定义的符号
【发布时间】:2016-12-06 09:56:15
【问题描述】:

我正在使用icc12制作一个包含三个文件的项目:

.s 文件,包含一系列汇编语言子程序

.h 文件,其中包含函数列表

.c 程序包含我调用子程序的主要代码

我的问题是,当我编译我的 C 程序时,编译器会显示以下错误:

 !ERROR file 'filename.o': undefined symbol '_lcd_putstr'
 !ERROR file 'filename.o': undefined symbol '_lcd_init'
 !ERROR file 'filename.o': undefined symbol '_lcd_move'
 !ERROR file 'filename.o': undefined symbol '_lcd_clear'

我一直在研究 .o 文件实际上是什么,并且我知道它是一个包含 CPU 可以理解的机器代码的目标文件。它们包含允许链接器查看它需要哪些符号才能工作的信息。尽管如此,我仍然不明白如何解决这些错误。我检查了任何语法错误,但似乎找不到任何语法错误。有人可以就如何在我的 .o 文件中“定义”这些符号提供一些帮助吗?

我的构建命令是

 #include <stdio.h>
 #include <mc9s12dp512.h>
 #include "lcd.h"

 int main (void)
 {
      unsigned char keycode;
      int keysave = 0;

      DDRB = 0x00;    /* make Port B an input port */

      lcd_init();  // initialise the lcd module
      lcd_clear(); // clear the lcd module

      // print the welcome message on the LCD module
      lcd_putstr(" message A ");

      // move the cursor position down a line
      lcd_move(1,1);
      lcd_putstr(" message B ");

      // move the cursor position down a line
      lcd_move(1,2);
      lcd_putstr(" message C ");

      // move the cursor position down a line
      lcd_move(1,3);
      lcd_putstr(" message D ");

摘自 _lcd_putstr 的汇编文件

 _lcd_putstr::
             pshx
             tfr     d,x             ; Transfer address of string to X
             ldaa    #WRDATA         ; Set up command for write data
             jsr     WriteBytes      ; Call subroutine to write byte to LCD
             pulx
             rts

【问题讨论】:

  • 请发布您的构建命令,并指出_lcd_xxx 函数的定义位置(即在哪个源文件中)。
  • 快速提问:icc 是用于 ImageCraft 编译器还是英特尔 C 编译器?
  • @user_1 我明白了。你能给我们看一下汇编文件的摘录吗?可能是您忘记将_lcd_putstr 等符号标记为全局。
  • @user_1 好吧,当在 Unix/POSIX 风格的环境中为本机主机(未交叉编译)开发时,命令将是 nm,而对于 Microsoft 的本机编译器,命令将是dumpbin。但是我不知道 ImageCraft 开发环境的等效命令会被调用,或者即使它有一个。
  • @user_1 尝试使用global 指令或任何调用它来使符号_lcd_putstr 全局化。默认情况下,目标文件中的符号是本地的,对链接器不可见。

标签: c assembly embedded microcontroller 68hc12


【解决方案1】:

通常,编译器在编译 c 源代码时会在标识符之前放置一个下划线。如果您的编译器这样做,您必须在汇编文件中的子例程名称中添加下划线,并在 .h 文件中省略它,例如:

汇编文件中的名称:_lcd_putstr

.h 文件中的原型:int lcd_putstr(void);

在.c文件中使用:n= lcd_putstr();


编辑:

“当我编译我的 C 程序时,编译器显示以下错误 [...]”

您向我们展示的错误不是编译器错误。它们是链接器错误。 C 文件被编译成 .o 文件。所有需要的 .o 和 lib 文件都由链接器组合成一个可执行文件。正是在这个阶段产生了错误信息:链接器找不到这些符号。

您必须指示您的编译器生成一个 .o 文件。然后您必须发出命令将对象链接到可执行文件中。看来您没有或没有发出此命令。请查阅您的开发工具的文档,了解如何使用所有必需对象发出链接命令。

【讨论】:

  • 对不起,我从来没有提到过,但我让他们准确地输入了你在那里的位置,我在 .s 文件中的子例程前面有一个下划线,后面有两个冒号。例如....' _lcd_putstr::'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-12
  • 1970-01-01
  • 2013-06-30
  • 1970-01-01
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多