首页 > 代码库 > C程序编译过程

C程序编译过程

  • 1.1程序被其他程序翻译成不同的格式

  1.hello.c

#include <stdio.h>

int main()
{
     printf("hello world\n");           
}

  2.编译过程



  3.编译系统
    预处理器、编译器、汇编器和链接器一起构成了编译系统

  预处理阶段。预处理器(cpp)根据以字符#开通的命令,修改原始的C程序。比如hello.c中第1行的#include<stdio.h>命令告诉预处理器读取系统头文件stdio.h的内容,并把它直接插入到程序的文本中。结果就得到了另一个C程序,通常是以.i作为文件扩展名

  预处理的过程主要处理包括以下过程:

  • 将所有的#define删除,并且展开所有的宏定义
  • 处理所有的条件预编译指令,比如#if #ifdef #elif #else #endif等
  • 处理#include 预编译指令,将被包含的文件插入到该预编译指令的位置。
  • 删除所有注释 “//”和”/* */”.
  • 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
  • 保留所有的#pragma编译器指令,因为编译器需要使用它们

  通常使用以下命令来进行预处理:

  gcc -E hello.c -o hello.i

  参数-E表示只进行预处理 或者也可以使用以下指令完成预处理过程

  cpp hello.c > hello.i      /*  cpp – The C Preprocessor  */

  1 # 1 "hello.c"
  2 # 1 "<built-in>"
  3 # 1 "<command-line>"
  4 # 1 "hello.c"
  5 # 1 "/usr/include/stdio.h" 1 3 4
  6 # 28 "/usr/include/stdio.h" 3 4
  7 # 1 "/usr/include/features.h" 1 3 4
  8 # 324 "/usr/include/features.h" 3 4
  9 # 1 "/usr/include/x86_64-linux-gnu/bits/predefs.h" 1 3 4
 10 # 325 "/usr/include/features.h" 2 3 4
 11 # 357 "/usr/include/features.h" 3 4
 12 # 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
 13 # 378 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4
 14 # 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
 15 # 379 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
 16 # 358 "/usr/include/features.h" 2 3 4
 17 # 389 "/usr/include/features.h" 3 4
 18 # 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4
 19 
 20 
 21 
 22 # 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
 23 # 5 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
 24 
 25 
 26 
 27 
 28 # 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4
 29 # 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
 30 # 390 "/usr/include/features.h" 2 3 4
 31 # 29 "/usr/include/stdio.h" 2 3 4
 32 
 33 
 34 
 35 
 36 
 37 # 1 "/usr/lib/gcc/x86_64-linux-gnu/4.6/include/stddef.h" 1 3 4
 38 # 212 "/usr/lib/gcc/x86_64-linux-gnu/4.6/include/stddef.h" 3 4
 39 typedef long unsigned int size_t;
 40 # 35 "/usr/include/stdio.h" 2 3 4
 41 
 42 # 1 "/usr/include/x86_64-linux-gnu/bits/types.h" 1 3 4
 43 # 28 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4
 44 # 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
 45 # 29 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4
 46 
 47 
 48 typedef unsigned char __u_char;
 49 typedef unsigned short int __u_short;
 50 typedef unsigned int __u_int;
 51 typedef unsigned long int __u_long;
 52 
 53 
 54 typedef signed char __int8_t;
 55 typedef unsigned char __uint8_t;
 56 typedef signed short int __int16_t;
 57 typedef unsigned short int __uint16_t;
 58 typedef signed int __int32_t;
 59 typedef unsigned int __uint32_t;
 60 
 61 typedef signed long int __int64_t;
 62 typedef unsigned long int __uint64_t;
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 typedef long int __quad_t;
 71 typedef unsigned long int __u_quad_t;
 72 # 131 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4
 73 # 1 "/usr/include/x86_64-linux-gnu/bits/typesizes.h" 1 3 4
 74 # 132 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4
 75 
 76 
 77 typedef unsigned long int __dev_t;
 78 typedef unsigned int __uid_t;
 79 typedef unsigned int __gid_t;
 80 typedef unsigned long int __ino_t;
 81 typedef unsigned long int __ino64_t;
 82 typedef unsigned int __mode_t;
 83 typedef unsigned long int __nlink_t;
 84 typedef long int __off_t;
 85 typedef long int __off64_t;
 86 typedef int __pid_t;
 87 typedef struct { int __val[2]; } __fsid_t;
 88 typedef long int __clock_t;
 89 typedef unsigned long int __rlim_t;
 90 typedef unsigned long int __rlim64_t;
 91 typedef unsigned int __id_t;
 92 typedef long int __time_t;
 93 typedef unsigned int __useconds_t;
 94 typedef long int __suseconds_t;
 95 
 96 typedef int __daddr_t;
 97 typedef long int __swblk_t;
 98 typedef int __key_t;
 99 
100 
101 typedef int __clockid_t;
102 
103 
104 typedef void * __timer_t;
105 
106 
107 typedef long int __blksize_t;
108 
109 
110 
111 
112 typedef long int __blkcnt_t;
113 typedef long int __blkcnt64_t;
114 
115 
116 typedef unsigned long int __fsblkcnt_t;
117 typedef unsigned long int __fsblkcnt64_t;
118 
119 
120 typedef unsigned long int __fsfilcnt_t;
121 typedef unsigned long int __fsfilcnt64_t;
122 
123 typedef long int __ssize_t;
124 
125 
126 
127 typedef __off64_t __loff_t;
128 typedef __quad_t *__qaddr_t;
129 typedef char *__caddr_t;
130 
131 
132 typedef long int __intptr_t;
133 
134 
135 typedef unsigned int __socklen_t;
136 # 37 "/usr/include/stdio.h" 2 3 4
137 # 45 "/usr/include/stdio.h" 3 4
138 struct _IO_FILE;
139 
140 
141 
142 typedef struct _IO_FILE FILE;
143 
144 
145 
146 
147 
148 # 65 "/usr/include/stdio.h" 3 4
149 typedef struct _IO_FILE __FILE;
150 # 75 "/usr/include/stdio.h" 3 4
151 # 1 "/usr/include/libio.h" 1 3 4
152 # 32 "/usr/include/libio.h" 3 4
153 # 1 "/usr/include/_G_config.h" 1 3 4
154 # 15 "/usr/include/_G_config.h" 3 4
155 # 1 "/usr/lib/gcc/x86_64-linux-gnu/4.6/include/stddef.h" 1 3 4
156 # 16 "/usr/include/_G_config.h" 2 3 4
157 
158 
159 
160 
161 # 1 "/usr/include/wchar.h" 1 3 4
162 # 83 "/usr/include/wchar.h" 3 4
163 typedef struct
164 {
165   int __count;
166   union
167   {
168 
169     unsigned int __wch;
170 
171 
172 
173     char __wchb[4];
174   } __value;
175 } __mbstate_t;
176 # 21 "/usr/include/_G_config.h" 2 3 4
177 
178 typedef struct
179 {
180   __off_t __pos;
181   __mbstate_t __state;
182 } _G_fpos_t;
183 typedef struct
184 {
185   __off64_t __pos;
186   __mbstate_t __state;
187 } _G_fpos64_t;
188 # 53 "/usr/include/_G_config.h" 3 4
189 typedef int _G_int16_t __attribute__ ((__mode__ (__HI__)));
190 typedef int _G_int32_t __attribute__ ((__mode__ (__SI__)));
191 typedef unsigned int _G_uint16_t __attribute__ ((__mode__ (__HI__)));
192 typedef unsigned int _G_uint32_t __attribute__ ((__mode__ (__SI__)));
193 # 33 "/usr/include/libio.h" 2 3 4
194 # 53 "/usr/include/libio.h" 3 4
195 # 1 "/usr/lib/gcc/x86_64-linux-gnu/4.6/include/stdarg.h" 1 3 4
196 # 40 "/usr/lib/gcc/x86_64-linux-gnu/4.6/include/stdarg.h" 3 4
197 typedef __builtin_va_list __gnuc_va_list;
198 # 54 "/usr/include/libio.h" 2 3 4
199 # 172 "/usr/include/libio.h" 3 4
200 struct _IO_jump_t; struct _IO_FILE;
201 # 182 "/usr/include/libio.h" 3 4
202 typedef void _IO_lock_t;
203 
204 
205 
206 
207 
208 struct _IO_marker {
209   struct _IO_marker *_next;
210   struct _IO_FILE *_sbuf;
211 
212 
213 
214   int _pos;
215 # 205 "/usr/include/libio.h" 3 4
216 };
217 
218 
219 enum __codecvt_result
220 {
221   __codecvt_ok,
222   __codecvt_partial,
223   __codecvt_error,
224   __codecvt_noconv
225 };
226 # 273 "/usr/include/libio.h" 3 4
227 struct _IO_FILE {
228   int _flags;
229 
230 
231 
232 
233   char* _IO_read_ptr;
234   char* _IO_read_end;
235   char* _IO_read_base;
236   char* _IO_write_base;
237   char* _IO_write_ptr;
238   char* _IO_write_end;
239   char* _IO_buf_base;
240   char* _IO_buf_end;
241 
242   char *_IO_save_base;
243   char *_IO_backup_base;
244   char *_IO_save_end;
245 
246   struct _IO_marker *_markers;
247 
248   struct _IO_FILE *_chain;
249 
250   int _fileno;
251 
252 
253 
254   int _flags2;
255 
256   __off_t _old_offset;
257 
258 
259 
260   unsigned short _cur_column;
261   signed char _vtable_offset;
262   char _shortbuf[1];
263 
264 
265 
266   _IO_lock_t *_lock;
267 # 321 "/usr/include/libio.h" 3 4
268   __off64_t _offset;
269 # 330 "/usr/include/libio.h" 3 4
270   void *__pad1;
271   void *__pad2;
272   void *__pad3;
273   void *__pad4;
274   size_t __pad5;
275 
276   int _mode;
277 
278   char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
279 
280 };
281 
282 
283 typedef struct _IO_FILE _IO_FILE;
284 
285 
286 struct _IO_FILE_plus;
287 
288 extern struct _IO_FILE_plus _IO_2_1_stdin_;
289 extern struct _IO_FILE_plus _IO_2_1_stdout_;
290 extern struct _IO_FILE_plus _IO_2_1_stderr_;
291 # 366 "/usr/include/libio.h" 3 4
292 typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes);
293 
294 
295 
296 
297 
298 
299 
300 typedef __ssize_t __io_write_fn (void *__cookie, __const char *__buf,
301      size_t __n);
302 
303 
304 
305 
306 
307 
308 
309 typedef int __io_seek_fn (void *__cookie, __off64_t *__pos, int __w);
310 
311 
312 typedef int __io_close_fn (void *__cookie);
313 # 418 "/usr/include/libio.h" 3 4
314 extern int __underflow (_IO_FILE *);
315 extern int __uflow (_IO_FILE *);
316 extern int __overflow (_IO_FILE *, int);
317 # 462 "/usr/include/libio.h" 3 4
318 extern int _IO_getc (_IO_FILE *__fp);
319 extern int _IO_putc (int __c, _IO_FILE *__fp);
320 extern int _IO_feof (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));
321 extern int _IO_ferror (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));
322 
323 extern int _IO_peekc_locked (_IO_FILE *__fp);
324 
325 
326 
327 
328 
329 extern void _IO_flockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
330 extern void _IO_funlockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
331 extern int _IO_ftrylockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
332 # 492 "/usr/include/libio.h" 3 4
333 extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict,
334    __gnuc_va_list, int *__restrict);
335 extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict,
336     __gnuc_va_list);
337 extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t);
338 extern size_t _IO_sgetn (_IO_FILE *, void *, size_t);
339 
340 extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int);
341 extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int);
342 
343 extern void _IO_free_backup_area (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
344 # 76 "/usr/include/stdio.h" 2 3 4
345 
346 
347 
348 
349 typedef __gnuc_va_list va_list;
350 # 91 "/usr/include/stdio.h" 3 4
351 typedef __off_t off_t;
352 # 103 "/usr/include/stdio.h" 3 4
353 typedef __ssize_t ssize_t;
354 
355 
356 
357 
358 
359 
360 
361 typedef _G_fpos_t fpos_t;
362 
363 
364 
365 
366 # 165 "/usr/include/stdio.h" 3 4
367 # 1 "/usr/include/x86_64-linux-gnu/bits/stdio_lim.h" 1 3 4
368 # 166 "/usr/include/stdio.h" 2 3 4
369 
370 
371 
372 extern struct _IO_FILE *stdin;
373 extern struct _IO_FILE *stdout;
374 extern struct _IO_FILE *stderr;
375 
376 
377 
378 
379 
380 
381 
382 extern int remove (__const char *__filename) __attribute__ ((__nothrow__ , __leaf__));
383 
384 extern int rename (__const char *__old, __const char *__new) __attribute__ ((__nothrow__ , __leaf__));
385 
386 
387 
388 
389 extern int renameat (int __oldfd, __const char *__old, int __newfd,
390        __const char *__new) __attribute__ ((__nothrow__ , __leaf__));
391 
392 
393 
394 
395 
396 
397 
398 
399 extern FILE *tmpfile (void) ;
400 # 210 "/usr/include/stdio.h" 3 4
401 extern char *tmpnam (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;
402 
403 
404 
405 
406 
407 extern char *tmpnam_r (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;
408 # 228 "/usr/include/stdio.h" 3 4
409 extern char *tempnam (__const char *__dir, __const char *__pfx)
410      __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) ;
411 
412 
413 
414 
415 
416 
417 
418 
419 extern int fclose (FILE *__stream);
420 
421 
422 
423 
424 extern int fflush (FILE *__stream);
425 
426 # 253 "/usr/include/stdio.h" 3 4
427 extern int fflush_unlocked (FILE *__stream);
428 # 267 "/usr/include/stdio.h" 3 4
429 
430 
431 
432 
433 
434 
435 extern FILE *fopen (__const char *__restrict __filename,
436       __const char *__restrict __modes) ;
437 
438 
439 
440 
441 extern FILE *freopen (__const char *__restrict __filename,
442         __const char *__restrict __modes,
443         FILE *__restrict __stream) ;
444 # 296 "/usr/include/stdio.h" 3 4
445 
446 # 307 "/usr/include/stdio.h" 3 4
447 extern FILE *fdopen (int __fd, __const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) ;
448 # 320 "/usr/include/stdio.h" 3 4
449 extern FILE *fmemopen (void *__s, size_t __len, __const char *__modes)
450   __attribute__ ((__nothrow__ , __leaf__)) ;
451 
452 
453 
454 
455 extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) ;
456 
457 
458 
459 
460 
461 
462 extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__));
463 
464 
465 
466 extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf,
467       int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__));
468 
469 
470 
471 
472 
473 extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf,
474          size_t __size) __attribute__ ((__nothrow__ , __leaf__));
475 
476 
477 extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
478 
479 
480 
481 
482 
483 
484 
485 
486 extern int fprintf (FILE *__restrict __stream,
487       __const char *__restrict __format, ...);
488 
489 
490 
491 
492 extern int printf (__const char *__restrict __format, ...);
493 
494 extern int sprintf (char *__restrict __s,
495       __const char *__restrict __format, ...) __attribute__ ((__nothrow__));
496 
497 
498 
499 
500 
501 extern int vfprintf (FILE *__restrict __s, __const char *__restrict __format,
502        __gnuc_va_list __arg);
503 
504 
505 
506 
507 extern int vprintf (__const char *__restrict __format, __gnuc_va_list __arg);
508 
509 extern int vsprintf (char *__restrict __s, __const char *__restrict __format,
510        __gnuc_va_list __arg) __attribute__ ((__nothrow__));
511 
512 
513 
514 
515 
516 extern int snprintf (char *__restrict __s, size_t __maxlen,
517        __const char *__restrict __format, ...)
518      __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4)));
519 
520 extern int vsnprintf (char *__restrict __s, size_t __maxlen,
521         __const char *__restrict __format, __gnuc_va_list __arg)
522      __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0)));
523 
524 # 418 "/usr/include/stdio.h" 3 4
525 extern int vdprintf (int __fd, __const char *__restrict __fmt,
526        __gnuc_va_list __arg)
527      __attribute__ ((__format__ (__printf__, 2, 0)));
528 extern int dprintf (int __fd, __const char *__restrict __fmt, ...)
529      __attribute__ ((__format__ (__printf__, 2, 3)));
530 
531 
532 
533 
534 
535 
536 
537 
538 extern int fscanf (FILE *__restrict __stream,
539      __const char *__restrict __format, ...) ;
540 
541 
542 
543 
544 extern int scanf (__const char *__restrict __format, ...) ;
545 
546 extern int sscanf (__const char *__restrict __s,
547      __const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__));
548 # 449 "/usr/include/stdio.h" 3 4
549 extern int fscanf (FILE *__restrict __stream, __const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf")
550 
551                                ;
552 extern int scanf (__const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf")
553                               ;
554 extern int sscanf (__const char *__restrict __s, __const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__))
555 
556                       ;
557 # 469 "/usr/include/stdio.h" 3 4
558 
559 
560 
561 
562 
563 
564 
565 
566 extern int vfscanf (FILE *__restrict __s, __const char *__restrict __format,
567       __gnuc_va_list __arg)
568      __attribute__ ((__format__ (__scanf__, 2, 0))) ;
569 
570 
571 
572 
573 
574 extern int vscanf (__const char *__restrict __format, __gnuc_va_list __arg)
575      __attribute__ ((__format__ (__scanf__, 1, 0))) ;
576 
577 
578 extern int vsscanf (__const char *__restrict __s,
579       __const char *__restrict __format, __gnuc_va_list __arg)
580      __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0)));
581 # 500 "/usr/include/stdio.h" 3 4
582 extern int vfscanf (FILE *__restrict __s, __const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf")
583 
584 
585 
586      __attribute__ ((__format__ (__scanf__, 2, 0))) ;
587 extern int vscanf (__const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf")
588 
589      __attribute__ ((__format__ (__scanf__, 1, 0))) ;
590 extern int vsscanf (__const char *__restrict __s, __const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__))
591 
592 
593 
594      __attribute__ ((__format__ (__scanf__, 2, 0)));
595 # 528 "/usr/include/stdio.h" 3 4
596 
597 
598 
599 
600 
601 
602 
603 
604 
605 extern int fgetc (FILE *__stream);
606 extern int getc (FILE *__stream);
607 
608 
609 
610 
611 
612 extern int getchar (void);
613 
614 # 556 "/usr/include/stdio.h" 3 4
615 extern int getc_unlocked (FILE *__stream);
616 extern int getchar_unlocked (void);
617 # 567 "/usr/include/stdio.h" 3 4
618 extern int fgetc_unlocked (FILE *__stream);
619 
620 
621 
622 
623 
624 
625 
626 
627 
628 
629 
630 extern int fputc (int __c, FILE *__stream);
631 extern int putc (int __c, FILE *__stream);
632 
633 
634 
635 
636 
637 extern int putchar (int __c);
638 
639 # 600 "/usr/include/stdio.h" 3 4
640 extern int fputc_unlocked (int __c, FILE *__stream);
641 
642 
643 
644 
645 
646 
647 
648 extern int putc_unlocked (int __c, FILE *__stream);
649 extern int putchar_unlocked (int __c);
650 
651 
652 
653 
654 
655 
656 extern int getw (FILE *__stream);
657 
658 
659 extern int putw (int __w, FILE *__stream);
660 
661 
662 
663 
664 
665 
666 
667 
668 extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
669      ;
670 
671 
672 
673 
674 
675 
676 extern char *gets (char *__s) ;
677 
678 # 662 "/usr/include/stdio.h" 3 4
679 extern __ssize_t __getdelim (char **__restrict __lineptr,
680           size_t *__restrict __n, int __delimiter,
681           FILE *__restrict __stream) ;
682 extern __ssize_t getdelim (char **__restrict __lineptr,
683         size_t *__restrict __n, int __delimiter,
684         FILE *__restrict __stream) ;
685 
686 
687 
688 
689 
690 
691 
692 extern __ssize_t getline (char **__restrict __lineptr,
693        size_t *__restrict __n,
694        FILE *__restrict __stream) ;
695 
696 
697 
698 
699 
700 
701 
702 
703 extern int fputs (__const char *__restrict __s, FILE *__restrict __stream);
704 
705 
706 
707 
708 
709 extern int puts (__const char *__s);
710 
711 
712 
713 
714 
715 
716 extern int ungetc (int __c, FILE *__stream);
717 
718 
719 
720 
721 
722 
723 extern size_t fread (void *__restrict __ptr, size_t __size,
724        size_t __n, FILE *__restrict __stream) ;
725 
726 
727 
728 
729 extern size_t fwrite (__const void *__restrict __ptr, size_t __size,
730         size_t __n, FILE *__restrict __s);
731 
732 # 734 "/usr/include/stdio.h" 3 4
733 extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,
734          size_t __n, FILE *__restrict __stream) ;
735 extern size_t fwrite_unlocked (__const void *__restrict __ptr, size_t __size,
736           size_t __n, FILE *__restrict __stream);
737 
738 
739 
740 
741 
742 
743 
744 
745 extern int fseek (FILE *__stream, long int __off, int __whence);
746 
747 
748 
749 
750 extern long int ftell (FILE *__stream) ;
751 
752 
753 
754 
755 extern void rewind (FILE *__stream);
756 
757 # 770 "/usr/include/stdio.h" 3 4
758 extern int fseeko (FILE *__stream, __off_t __off, int __whence);
759 
760 
761 
762 
763 extern __off_t ftello (FILE *__stream) ;
764 # 789 "/usr/include/stdio.h" 3 4
765 
766 
767 
768 
769 
770 
771 extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos);
772 
773 
774 
775 
776 extern int fsetpos (FILE *__stream, __const fpos_t *__pos);
777 # 812 "/usr/include/stdio.h" 3 4
778 
779 # 821 "/usr/include/stdio.h" 3 4
780 
781 
782 extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
783 
784 extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
785 
786 extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
787 
788 
789 
790 
791 extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
792 extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
793 extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
794 
795 
796 
797 
798 
799 
800 
801 
802 extern void perror (__const char *__s);
803 
804 
805 
806 
807 
808 
809 # 1 "/usr/include/x86_64-linux-gnu/bits/sys_errlist.h" 1 3 4
810 # 27 "/usr/include/x86_64-linux-gnu/bits/sys_errlist.h" 3 4
811 extern int sys_nerr;
812 extern __const char *__const sys_errlist[];
813 # 851 "/usr/include/stdio.h" 2 3 4
814 
815 
816 
817 
818 extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
819 
820 
821 
822 
823 extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
824 # 870 "/usr/include/stdio.h" 3 4
825 extern FILE *popen (__const char *__command, __const char *__modes) ;
826 
827 
828 
829 
830 
831 extern int pclose (FILE *__stream);
832 
833 
834 
835 
836 
837 extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
838 # 910 "/usr/include/stdio.h" 3 4
839 extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
840 
841 
842 
843 extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
844 
845 
846 extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
847 # 940 "/usr/include/stdio.h" 3 4
848 
849 # 2 "hello.c" 2
850 
851 int main()
852 {
853  printf("hello world!\n");
854 }
hello.i

 

  编译阶段。编译器(ccl)将文本文件hello.i翻译成文本文件hello.s,它包含一个汇编语言程序。汇编语言程序中的每条语句都以一种标准的文本格式确切地描述了一条低级机器语言指令。汇编语言是非常有用的,因为他为不同高级语言的不同编译器提供了通用的输出语言。例如,C编译器和Fortran编译器产生的输出文件用的都是一样的汇编语言。

  编译过程就是把预处理完的文件进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码。

  gcc –S hello.i –o hello.s

 1     .file    "hello.c"
 2     .section    .rodata
 3 .LC0:
 4     .string    "hello world!"
 5     .text
 6     .globl    main
 7     .type    main, @function
 8 main:
 9 .LFB0:
10     .cfi_startproc
11     pushq    %rbp
12     .cfi_def_cfa_offset 16
13     .cfi_offset 6, -16
14     movq    %rsp, %rbp
15     .cfi_def_cfa_register 6
16     movl    $.LC0, %edi
17     call    puts
18     popq    %rbp
19     .cfi_def_cfa 7, 8
20     ret
21     .cfi_endproc
22 .LFE0:
23     .size    main, .-main
24     .ident    "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
25     .section    .note.GNU-stack,"",@progbits
hello.s

  汇编阶段。汇编器(as)将hello.s翻译成机器语言指令,并把这些指令打包成一种叫做可充定位目标程序(relocatable object program)的格式,并将结果保存在目标文件hello.o中,hello.o文件是一个二进制文件,它的字节编码是机器语言指令而不是字符。如果我们在文本编辑器中打开hello.o文件,看到的将是一堆乱码。

  汇编器是将汇编代码转变成机器可以执行的命令,每一个汇编语句几乎都对应一条机器指令。汇编相对于编译过程比较简单,根据汇编指令和机器指令的对照表一一翻译即可。

  $ gcc –c hello.c –o hello.o

  或者

  $ as hello.s –o hello.co

  由于hello.o的内容为机器码,不能以普通文本形式的查看

  连接阶段。请注意,hello程序调用了printf函数,他是每个C编译器都会提供的标准C库中的一个函数。printf函数存在于一个名为printf.o程序中。链接器(ld)就负责处理这种合并。结果就得到hello文件,他是一个可执行目标文件(或者简称可执行文件),可以被加载到内存,由系统执行。

  通过调用链接器ld来链接程序运行需要的一大堆目标文件,以及所依赖的其它库文件,最后生成可执行文件。

  

  参考:

  书籍:《深入理解计算机系统》

  博客:http://blog.csdn.net/koudaidai/article/details/8092647