首页 > 代码库 > 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 }
编译阶段。编译器(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
汇编阶段。汇编器(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