Chinaunix首页 | 论坛 | 博客
  • 博客访问: 147498
  • 博文数量: 29
  • 博客积分: 717
  • 博客等级: 上士
  • 技术积分: 352
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-16 16:17
文章分类

全部博文(29)

文章存档

2013年(4)

2012年(4)

2011年(21)

我的朋友

分类: LINUX

2013-02-21 16:49:20

You can download from site: 


预备知识,阅读文章“as中常见伪指令.word .align .balign[lw] .macro .globl”

C源文件到ELF可执行文件的生成过程

1. 编译器的预处理

2. C源代码转换为汇编代码

3. 生成目标文件

4. 将目标文件链接为ELF可执行文件


ELF文件类型共有4种类型

1. 可重定位文件relocatable file

执行file xx.o,其中xx表示编译过程生成的目标文件

返回ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

2. 可执行文件executable file

执行file /bin/sh

ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

3. 共享目标文件share object file

执行file /lib/libmemusage.so

/lib/libmemusage.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped

4. 核心转储文件core dump file

执行file /proc/kcore

ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from '-3b3e-428f-91d0-1a730571'


  • 编写C代码

现在通过举例说明整个编译过程,首先建立show.c和mian.c文件,其中show.c文件的内容如下

#include

void show()

{

    printf ("this program is used to test ld\n");

}

mian.c的内容如下

extern void show(); 

int main()

{

    show();

    return 0;

}


  • C源代码转换为汇编代码

用gcc加上-save-temps选项编译完成以后,可以看到汇编文件show.s内容如下

         .file  "show.c"

         .section    .rodata

         .align 4

.LC0:

         .string      "this program is used to test ld"

         .text

.globl show                                           

.type         show, @function 

show:

         pushl         %ebp

         movl          %esp, %ebp

         subl  $24, %esp

         movl          $.LC0, (%esp)

         call   puts

         leave

         ret

         .size show, .-show

         .ident        "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"

         .section    .note.GNU-stack,"",@progbits

从汇编文件show.s里可以发现汇编文件里包含了很多的伪指令,其中align4表示16字节对齐,globl是的show符号对ld可见,即全局的。所有汇编文件.text section最后都会放在ELF文件的.text section


  • 生成目标文件

对show.o进行反汇编(objdump –d show.o)

Disassembly of section .text:

00000000 :

   0:        55                                push   %ebp

   1:        89 e5                           mov    %esp,%ebp

   3:        83 ec 18                      sub    $0x18,%esp

   6:        c7 04 24 00 00 00 00                movl   $0x0,(%esp)

   d:        e8 fc ff ff ff                                 call    e

  12:       c9                               leave 


  13:       c3                               ret    

对main.o进行反汇编(objdump –d main.o)

Disassembly of section .text: 

00000000

:

   0:        55                              push   %ebp

   1:        89 e5                         mov    %esp,%ebp

   3:        83 e4 f0                     and    $0xfffffff0,%esp

   6:        e8 fc ff ff ff                           call   7

   b:        b8 00 00 00 00                    mov    $0x0,%eax

  10:        89 ec                         mov    %ebp,%esp

  12:        5d                              pop    %ebp

  13:        c3                              ret  

而目标文件的生成也很简单,只是把汇编文件进行编译为对应机器码。该过程没有按照伪指令进行对齐边界,也没有进行的地址修正,对需要修正的地址只是在当前地址上+1.


  • 将目标文件链接为ELF可执行文件

链接器最后将所有的目标文件链接为ELF可执行文件,对ELF文件反汇编内容如下

080483e4

:

 80483e4:        55                             push   %ebp

 80483e5:        89 e5                        mov    %esp,%ebp

 80483e7:        83 e4 f0                    and    $0xfffffff0,%esp

 80483ea:        e8 09 00 00 00         call        80483f8

 80483ef:         b8 00 00 00 00         mov    $0x0,%eax

 80483f4:         89 ec                         mov    %ebp,%esp

 80483f6:         5d                             pop    %ebp

 80483f7:         c3                              ret    


080483f8 :

 80483f8:         55                                 push   %ebp

 80483f9:         89 e5                            mov    %esp,%ebp

 80483fb:         83 ec 18                       sub    $0x18,%esp

 80483fe:         c7 04 24 d0 84 04 08   movl   $0x80484d0,(%esp)

 8048405:        e8 0e ff ff ff                   call   8048318

 804840a:        c9                                 leave 

 804840b:        c3                                 ret   

 804840c:        90                                 nop

 804840d:        90                                nop

 804840e:        90                                nop

 804840f:         90                                nop

在链接器链接完成以后可以看出main函数调用show函数的地址和show函数对printf函数的地址都变成绝对地址,而且程序在最后加入了4条nop操作,使得以16字节对齐。


阅读(2409) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~