【问题标题】:How to link a C object file with a Assembly Language object file?如何将 C 目标文件与汇编语言目标文件链接?
【发布时间】:2012-01-31 05:53:32
【问题描述】:

我在链接 2 个目标文件时遇到问题,其中一个是从汇编语言源文件生成的,另一个是从 C 源文件生成的。

C源代码:

//main2.c
extern int strlength(char *);
int main(){
    char * test = "hello";
    int num = strlength(test);
    return num;
}

汇编源代码:

#strlength.s
.include "Linux32.s"

.section .text
.globl strlength
.type strlength, @function
strlength:
 pushl %ebp
 movl %esp, %ebp
 movl $0, %ecx
 movl 8(%ebp), %edx
read_next_byte:
 movb (%edx), %al
 cmpb $END_OF_FILE, %al
 jle end
 incl %edx
 incl %ecx
 jmp read_next_byte
end:
 movl %ecx, %eax
 popl %ebp
 ret

当我像这样使用 'gcc' 编译和运行时:

gcc main2.c strlength.s -m32 -o test
./test
echo $?

我得到 5,这是正确的。但是,当我单独编译/组装然后与'ld'链接时 像这样:

as strlength.s --32 -o strlength.o
cc main2.c -m32 -o main2.o
ld -melf_i386 -e main main2.o strlength.o -o test
./test

我遇到了分段错误。这是什么原因造成的?我没有 100% 正确地遵循 C 调用约定吗?

【问题讨论】:

    标签: c linux assembly ld gnu-assembler


    【解决方案1】:

    您还需要链接crt1.o(可能有不同的名称,包含必要的代码,直到可以调用main)和必要的库。 GCC 通常还需要链接到libgcc.so,其中包含必要的辅助函数(例如,在 32 位系统上进行 64 位计算时)以及其他系统库。例如,在我的 Mac 上,它还需要链接到 libSystem,其中还包含常用的 C 函数,如 printf。在 Linux 上,通常是 libc

    请注意,您的程序不能直接以main 开头(就像您尝试使用ld .. -e main 一样),入口点需要在调用C 函数main 之前设置一些东西。这就是前面提到的crt1.o 正在做的事情。我猜分段错误是缺少设置的结果。

    要查看 GCC 在您的系统上究竟做了什么,请调用:

    gcc main2.c strlength.s -m32 -o test -v
    

    【讨论】:

      【解决方案2】:

      ld -melf_i386 -e main main2.o strlength.o -o test

      不要那样做。改为这样做:

      gcc -m32 main2.o strlength.o -o test
      

      (您可能不应该将您的测试可执行文件称为 test,因为它可能与大多数 UNIX 系统上的标准 /bin/test 冲突。)

      说明:UNIX 二进制文件通常从main 开始执行。它们开始在一个名为_start 的函数中执行,该函数来自crt1.o 或类似的(“C 运行时启动”)。 那个文件是 libc 的一部分,它安排了各种初始化,这是正确启动应用程序所必需的。

      您的程序实际上不需要来自libc任何东西,这就是您能够将它与ld 链接的原因。

      但是,请考虑在您的 main 返回后会发生什么。 通常crt1.o 中的代码将执行(等效于)exit(main(argc, argv));。由于您在没有crt1.o 的情况下链接,因此没有人为您完成最终的exit,因此代码返回到...未定义的位置并立即崩溃。

      【讨论】:

        猜你喜欢
        • 2012-12-19
        • 1970-01-01
        • 2012-09-24
        • 1970-01-01
        • 1970-01-01
        • 2018-04-13
        • 2019-02-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多