Hovernoon 发表于 2010-05-29 23:30

关于linux下编译链接的详细步骤

今天在ubuntu上按照深入理解计算机系统上给的步骤做了个实验:

a.c:
extern int sum(int, int);
int main()
{
      int a = 3;
      int b = 4;
      int c = 8;
      c = sum(a , b);
      return 0;
}
sum.c:
int sum(int a, int b)
{
       return a + b;
}

cpp a.c a.i(预处理)
cc1 a.i -o a.s(获得汇编代码)
as -o a.o a.s (汇编器汇编得到二进制文件)
同样的步骤得到sum.o
ld -o a a.o sum.o (链接)
此时出现warning,大概是说未找到_start符号,设为默认......
./a 出现segment fault
请问以上的步骤为什么会出现错误,是不是少了什么命令,还是命令少加了什么选项。请大虾们赐教。

yoyocall 发表于 2010-05-30 08:59

ld -o a a.o sum.o --dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.4/crtbegin.o /usr/lib/gcc/i486-linux-gnu/4.4/crtend.o /usr/lib/crtn.o -lc

EricFisher 发表于 2010-05-30 10:07

如果执行

gcc -o a a.o sum.o -v

你就可以看到gcc调用ld时,所传递给ld的命令行参数,包括额外要链接的运行时库

Hovernoon 发表于 2010-06-02 12:35

3ks yoyocall and EricFisher.

Hovernoon 发表于 2010-06-02 13:01

回复 2# yoyocall

3ks,yoyocall
可否解释一下这些加上的这些库有什么作用?

accessory 发表于 2010-06-04 02:39

那些库主要是运行时库,准备一些运行环境,比如堆栈,进程的起始,终止等。
虽然从C语言的角度看,程序从MAIN开始,到MAIN退出结束。但是从OS的角度看,这之前和之后还有很多东西。

其实如果你想搞明白的话,OBJDUMP 下最后生成的2个文件,看看他们的不同就知道了。

我自己看了下,正常的程序会添加了一堆的辅助函数。

================================
搭车问个问题:

我直接把A.S改了下,不用堆栈,不调用SUM函数,直接把2个寄存器相加,基本就3行代码:
MOVQ $1, %RAX
MOVQ $2, %RBX
ADDQ %RAX, %RBX

运行的话,还是有有SEG FAULT. 用GDB看了下。这3句执行都没问题的。死在了之后的地方。

进程退出的时候还要做哪些特殊处理?有了解的来指点下?

accessory 发表于 2010-06-04 03:14

找到答案了。退出的时候要调用SYS_EXIT. 也就是在结束的地方需要如下代码:

        xorl %eax, %eax                # %eax = 0
        incl %eax                # %eax = 1 system call _exit ()
        xorl %ebx, %ebx                # %ebx = 0 normal program return code
        int $0x80                # execute system call _exit ()

PS: 上面这段是32位的,我之前那贴是64位,根据情况调整下即可。

Hovernoon 发表于 2010-06-04 16:56

回复 6# accessory


    accessory, 3ks for your answer
我记得大一的时候在windows下用borland的开发环境,那个里面的ld用起来时很方便的,不加参数就可以直接把.o文件链接成可执行文件,没想到gnu的ld用起来这么到讲究。

accessory 发表于 2010-06-04 22:44

看你怎么想了吧。
我觉得BORLAND那种,从你说的来看,比如适合新手。
GCC这种,更加灵活些,但是用起来更麻烦些。其实GCC生成的也是可执行文件啊。看你自己想执行啥了。:P

EricFisher 发表于 2010-06-04 23:44

曾经的 borland传奇
页: [1]
查看完整版本: 关于linux下编译链接的详细步骤