实例讲解编译过程

来源:互联网 发布:软件怎开发的 编辑:程序博客网 时间:2024/04/30 06:47

1code

1.1结构

.
|-- base1.h                           //内联函数的定义
|-- base2.c                           //普通函数的定义
|-- base2.h                          //普通函数的声明
|-- call1.c                             //分别调用base1 base2的模块
|-- call1.h                           
|-- call2.c                            //分别调用base1 base2的模块
|-- call2.h
`-- main.c                          //分别调用call1 call2的模块

  1.2base1.h

1 #ifndef _BASE1_H_
2 #define _BASE1_H_
3
4 int base1_a = 10;
5
6 inline int base1_printf()
7 {
8
9 }
10
11 #endif

1.3base2.h


  1 #ifndef _BASE2_H_
  2 #define _BASE2_H_
  3 int base2_a = 20;
  4
  5 extern int base2_printf();
  6
  7
  8 #endif

1.4base2.c

  1 #include "base2.h"
  2
  3 int base2_printf()
  4 {
  5 }

1.5call1.h

  1 #ifndef _CALL1_H_
  2 #define _CALL1_H_
  3
  4 int call_a = 30;
  5
  6 extern int call1_printf();
  7
  8 #endi

1.6call1.c

  1 #include "base1.h"
  2 #include "base2.h"
  3
  4 int call1_printf()
  5 {
  6         base1_printf();
  7         base2_printf();
  8 }


1.7call2.h

  1 #ifndef _CALL2_H_
  2 #define _CALL2_H_
  3
  4 int call_a = 30;
  5
  6 extern int call2_printf();
  7
  8 #endif

1.8call2.c

  1 #include "base1.h"
  2 #include "base2.h"
  3
  4 int call2_printf()
  5 {
  6         base1_printf();
  7         base2_printf();
  8 }


2base2.c


2.1预编译:gcc -E -o base2.i base2.c

2.1.1 cat base2.i

# 1 "base2.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "base2.c"
# 1 "base2.h" 1


int base2_a = 20;

extern int base2_printf();
# 2 "base2.c" 2

int base2_printf()
{
}

2.1.2总结

将base2.h base2.c中内容插入到同一文件base2.i文件中

2.2编译:gcc -S -o base2.s base2.i

2.2.1cat base2.s

    .file    "base2.c"
.globl base2_a
    .data
    .align 4
    .type    base2_a, @object
    .size    base2_a, 4
base2_a:
    .long    20
    .text
.globl base2_printf
    .type    base2_printf, @function
base2_printf:
    pushl    %ebp
    movl    %esp, %ebp
    popl    %ebp
    ret
    .size    base2_printf, .-base2_printf
    .ident    "GCC: (Debian 4.4.5-8) 4.4.5"
    .section    .note.GNU-stack,"",@progbits

2.2.2总结


2.3汇编:gcc -c -o base2.o base2.s

2.3.1 nm -A base2.o

base2.o:00000000 D base2_a
base2.o:00000000 T base2_printf

3call1.c

3.1预编译:gcc -E -o call1.i call1.c

3.1.1 cat call1.i

# 1 "call1.c"

# 1 "<built-in>"

# 1 "<command-line>"

# 1 "call1.c"

# 1 "base1.h" 1

int base1_a = 10;

inline int base1_printf()

{


}

# 2 "call1.c" 2

# 1 "base2.h" 1

int base2_a = 20;

extern int base2_printf();

# 3 "call1.c" 2

int call1_printf()

{

  base1_printf();

  base2_printf();

}


3.1.2总结

将base1.h base2.h中内容插入到同一文件call1.i文件中

3.2编译:gcc -S -o call1.s call1.i

3.2.1cat call1.s

    1         .file   "call1.c"

  2 .globl base1_a

  3         .data

  4         .align 4

  5         .type   base1_a, @object

  6         .size   base1_a, 4

  7 base1_a:

  8         .long   10

  9         .text

 10 .globl base1_printf

 11         .type   base1_printf, @function

 12 base1_printf:

 13         pushl   %ebp

 14         movl    %esp, %ebp

 15         popl    %ebp

 16         ret

 17         .size   base1_printf, .-base1_printf

 18 .globl base2_a

 19         .data

 20         .align 4

 21         .type   base2_a, @object

 22         .size   base2_a, 4

 23 base2_a:

 24         .long   20

 25         .text

 26 .globl call1_printf

 27         .type   call1_printf, @function

 28 call1_printf:

 29         pushl   %ebp

 30         movl    %esp, %ebp

 31         subl    $8, %esp

 32         call    base1_printf

 33         call    base2_printf

 34         leave

 35         ret

 36         .size   call1_printf, .-call1_printf

 37         .ident  "GCC: (Debian 4.4.5-8) 4.4.5"

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


2.2.2总结

好像inline base1_printf()的调用和base2_printf()没有什么区别


3.3汇编:gcc -c -o call1.o call1.s

3.3.1 nm -a call1.o

00000000 b .bss

00000000 n .comment

00000000 d .data

00000000 n .note.GNU-stack

00000000 t .text

00000000 D base1_a

00000000 T base1_printf

00000004 D base2_a

         U base2_printf

00000000 a call1.c

00000005 T call1_printf

3.3.2 总结

base2_printf base1_printf好像有点不一样了

4.同理进行call2.c的相同编译

4.main.c过程


4.1预编译:gcc -E -o main.i main.c

4.1.1 cat main.i

  1 # 1 "main.c"
  2 # 1 "<built-in>"
  3 # 1 "<command-line>"
  4 # 1 "main.c"
  5 # 1 "call1.h" 1
  6
  7
  8
  9 int call_a = 30;
 10
 11 extern int call1_printf();
 12 # 2 "main.c" 2
 13 # 1 "call2.h" 1
 14
 15
 16
 17 int call_a = 30;
 18
 19 extern int call2_printf();
 20 # 3 "main.c" 2
 21
 22
 23 int main(void)
 24 {
 25  call1_printf();
 26  call2_printf();
 27  call_a = 40;
 28
 29 }

4.2编译:gcc -S -o main.s main.i

call2.h:4: error: redefinition of 'call_a'
call1.h:4: note: previous definition of 'call_a' was here

将call2.h中int call_a = 30;改为int call2_a = 30;

gcc base2.o call1.o call2.o main.o -o main
call2.o: In function `base1_printf':
call2.c:(.text+0x0): multiple definition of `base1_printf'
call1.o:call1.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status

1base1.h

 #ifndef _BASE1_H_
2 #define _BASE1_H_
3
4 int base1_a = 10;
5
6 static inline int base1_printf()
7 {
8
9 }
10
11 #endif