【问题标题】:Problems with calling an assembly function from C从 C 调用汇编函数的问题
【发布时间】:2012-03-21 17:42:35
【问题描述】:

(在 64 位 Windows 7 上运行 MingW,在 Kubuntu 上运行 GCC)

这可能只是一个 MingW 问题,但它在至少一个 Kubuntu 安装上也失败了,所以我很怀疑。

我有一个简短的 C 程序,它应该调用一个汇编函数。我使用 nasm 编译汇编器,使用 MingW 的 gcc 实现编译 c 程序。两者通过 makefile 链接在一起 - bog-simple。然而,链接在声称外部函数是“未定义引用”的声明上失败了

makefile 的相关部分:

assign0: ass0.o main.o 
gcc -v -m32 -g -Wall -o assign0 ass0.o main.o 


    main.o: main.c 
         gcc -g -c -Wall -m32 -o main.o main.c 

    ass0.o: ass0.s
     nasm -g -f elf -w+all -o ass0.o ass0.s

汇编文件的开头:

section .data                       ; data section, read-write
    an:    DD 0                 ; this is a temporary var

section .text                       ; our code is always in the .text section
    global do_str               ; makes the function appear in global scope
    extern printf               

do_str:                             ; functions are defined as labels
[Just Code]

还有c文件的声明:

extern int do_str(char* a);

这至少在一个 Kubuntu 安装上有效,在另一个上失败,在 MingW 上失败。有人有想法吗?

【问题讨论】:

  • 有时_ 会被添加到符号名称之前。您收到的确切错误消息是什么?
  • 你试过在链接器命令行上交换 {ass0.o main.o} 吗?
  • @wildplasser,为什么会有不同?
  • 您想在程序集端添加_,而不是 C 端,如果这实际上是问题所在。不能有与源代码行相关的“未定义引用”错误 - 这是一个链接错误。请在此处复制并粘贴全文。

标签: c assembly


【解决方案1】:

...声称外部函数是“未定义的引用”

哈哈!链接者不会“声称”虚假信息。你不会说服它通过坚持你是对的还是错的来改变主意。毫不拖延地接受工具告诉你的事实。这是快速识别问题的关键。

几乎每个 C 编译器,包括您正在使用的编译器,都会生成带有下划线前缀的全局符号,以尽量减少与汇编语言符号的名称冲突。例如,将您的代码更改为

extern _printf
...
call  _printf

关于 printf 未定义的错误消息将消失。如果您确实获得了对_printf 的未定义引用,那是因为链接器没有访问C 运行时库。链接命令可能很难正确。通常这样做不是很有教育意义,所以从一个工作项目中学习,或者寻找一个例子。这就是 IDE 非常有用的方式。

至于调用汇编函数的 C 代码,通常使用 C 的约定来编写汇编函数是最容易的:

    global  _do_str

_do_str:

或者,您可以声明函数以使用 Pascal 调用约定:

extern int pascal do_str ( whatever parameters are needed);
...

retval = do_str ("hello world");

Pascal 调用约定与 C 有很大的不同:它不会在符号前加上前导下划线,调用者负责在返回后删除参数,并且参数的顺序不同,可能带有某些参数数据类型在寄存器中而不是在堆栈中传递。有关所有详细信息,请参阅编译器参考。

【讨论】:

    【解决方案2】:

    C 编译器可能会以不同的方式调用实际的“函数”,例如_do_str 而不是 do_str。名称修改并不总是发生可能取决于系统(当然也取决于编译器)。尝试调用 asm 函数 _do_str。使用正确的attributes(在 gcc 中)也可以解决问题。还有read this

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      • 2018-10-13
      • 1970-01-01
      • 1970-01-01
      • 2014-07-12
      相关资源
      最近更新 更多