首页 > 代码库 > hello world的本质-----预编译,编译,汇编,链接
hello world的本质-----预编译,编译,汇编,链接
今天开始会开始讲述linux下程序的本质。这关系着一个程序员内功的修养以及后续读android源代码的基础。
大家都知道一个程序从编写完成到最后运行成功。要经历4个步骤,一共是预处理,编译,汇编,和链接。
首先我们编写一个最简单的hello world 程序。
1 #include<stdio.h>2 int main()3 {4 printf("hello world!\n");5 return 0;6 7 }
然后 在命令行输入命令
gcc -E hello.c -o hello.i
这个命令就是用来生成预处理后的文件的。
我们可以打开这个文件,看看里面的内容。
1 # 1 "hello.c" 2 # 1 "<command-line>" 3 # 1 "/usr/include/stdc-predef.h" 1 3 4 4 # 1 "<command-line>" 2 5 # 1 "hello.c" 6 # 1 "/usr/include/stdio.h" 1 3 4 7 # 27 "/usr/include/stdio.h" 3 4 8 # 1 "/usr/include/features.h" 1 3 4 9 # 374 "/usr/include/features.h" 3 4 10 # 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4 11 # 385 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4 12 # 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 13 # 386 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4 14 # 375 "/usr/include/features.h" 2 3 4 15 # 398 "/usr/include/features.h" 3 4 16 # 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4 17 # 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4 18 # 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4 19 # 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4 20 # 399 "/usr/include/features.h" 2 3 4 21 # 28 "/usr/include/stdio.h" 2 3 4 22 23 24 25 26 27 # 1 "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h" 1 3 4 28 # 212 "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h" 3 4 29 typedef long unsigned int size_t; 30 # 34 "/usr/include/stdio.h" 2 3 4 31 32 # 1 "/usr/include/x86_64-linux-gnu/bits/types.h" 1 3 4 33 # 27 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4 34 # 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 35 # 28 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4 36 37 38 typedef unsigned char __u_char; 39 typedef unsigned short int __u_short; 40 typedef unsigned int __u_int; 41 typedef unsigned long int __u_long; 42 43 44 typedef signed char __int8_t; 45 typedef unsigned char __uint8_t; 46 typedef signed short int __int16_t; 47 typedef unsigned short int __uint16_t; 48 typedef signed int __int32_t; 49 typedef unsigned int __uint32_t; 50 51 typedef signed long int __int64_t; 52 typedef unsigned long int __uint64_t; 53 54 55 56 57 58 59 60 typedef long int __quad_t; 61 typedef unsigned long int __u_quad_t; 62 # 121 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4 63 # 1 "/usr/include/x86_64-linux-gnu/bits/typesizes.h" 1 3 4 64 # 122 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4 65 66 67 typedef unsigned long int __dev_t; 68 typedef unsigned int __uid_t; 69 typedef unsigned int __gid_t; 70 typedef unsigned long int __ino_t; 71 typedef unsigned long int __ino64_t; 72 typedef unsigned int __mode_t; 73 typedef unsigned long int __nlink_t; 74 typedef long int __off_t; 75 typedef long int __off64_t; 76 typedef int __pid_t; 77 typedef struct { int __val[2]; } __fsid_t; 78 typedef long int __clock_t; 79 typedef unsigned long int __rlim_t; 80 typedef unsigned long int __rlim64_t; 81 typedef unsigned int __id_t; 82 typedef long int __time_t; 83 typedef unsigned int __useconds_t; 84 typedef long int __suseconds_t; 85 86 typedef int __daddr_t; 87 typedef int __key_t; 88 89 90 typedef int __clockid_t; 91 92 93 typedef void * __timer_t; 94 95 96 typedef long int __blksize_t; 97 98 99 100 101 typedef long int __blkcnt_t;102 typedef long int __blkcnt64_t;103 104 105 typedef unsigned long int __fsblkcnt_t;106 typedef unsigned long int __fsblkcnt64_t;107 108 109 typedef unsigned long int __fsfilcnt_t;110 typedef unsigned long int __fsfilcnt64_t;111 112 113 typedef long int __fsword_t;114 115 typedef long int __ssize_t;116 117 118 typedef long int __syscall_slong_t;119 120 typedef unsigned long int __syscall_ulong_t;121 122 123 124 typedef __off64_t __loff_t;125 typedef __quad_t *__qaddr_t;126 typedef char *__caddr_t;127 128 129 typedef long int __intptr_t;130 131 132 typedef unsigned int __socklen_t;133 # 36 "/usr/include/stdio.h" 2 3 4134 # 44 "/usr/include/stdio.h" 3 4135 struct _IO_FILE;136 137 138 139 typedef struct _IO_FILE FILE;140 141 142 143 144 145 # 64 "/usr/include/stdio.h" 3 4146 typedef struct _IO_FILE __FILE;147 # 74 "/usr/include/stdio.h" 3 4148 # 1 "/usr/include/libio.h" 1 3 4149 # 31 "/usr/include/libio.h" 3 4150 # 1 "/usr/include/_G_config.h" 1 3 4151 # 15 "/usr/include/_G_config.h" 3 4152 # 1 "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h" 1 3 4153 # 16 "/usr/include/_G_config.h" 2 3 4154 155 156 157 158 # 1 "/usr/include/wchar.h" 1 3 4159 # 82 "/usr/include/wchar.h" 3 4160 typedef struct161 {162 int __count;163 union164 {165 166 unsigned int __wch;167 168 169 170 char __wchb[4];171 } __value;172 } __mbstate_t;173 # 21 "/usr/include/_G_config.h" 2 3 4174 typedef struct175 {176 __off_t __pos;177 __mbstate_t __state;178 } _G_fpos_t;179 typedef struct180 {181 __off64_t __pos;182 __mbstate_t __state;183 } _G_fpos64_t;184 # 32 "/usr/include/libio.h" 2 3 4185 # 49 "/usr/include/libio.h" 3 4186 # 1 "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h" 1 3 4187 # 40 "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h" 3 4188 typedef __builtin_va_list __gnuc_va_list;189 # 50 "/usr/include/libio.h" 2 3 4190 # 144 "/usr/include/libio.h" 3 4191 struct _IO_jump_t; struct _IO_FILE;192 # 154 "/usr/include/libio.h" 3 4193 typedef void _IO_lock_t;194 195 196 197 198 199 struct _IO_marker {200 struct _IO_marker *_next;201 struct _IO_FILE *_sbuf;202 203 204 205 int _pos;206 # 177 "/usr/include/libio.h" 3 4207 };208 209 210 enum __codecvt_result211 {212 __codecvt_ok,213 __codecvt_partial,214 __codecvt_error,215 __codecvt_noconv216 };217 # 245 "/usr/include/libio.h" 3 4218 struct _IO_FILE {219 int _flags;220 221 222 223 224 char* _IO_read_ptr;225 char* _IO_read_end;226 char* _IO_read_base;227 char* _IO_write_base;228 char* _IO_write_ptr;229 char* _IO_write_end;230 char* _IO_buf_base;231 char* _IO_buf_end;232 233 char *_IO_save_base;234 char *_IO_backup_base;235 char *_IO_save_end;236 237 struct _IO_marker *_markers;238 239 struct _IO_FILE *_chain;240 241 int _fileno;242 243 244 245 int _flags2;246 247 __off_t _old_offset;248 249 250 251 unsigned short _cur_column;252 signed char _vtable_offset;253 char _shortbuf[1];254 255 256 257 _IO_lock_t *_lock;258 # 293 "/usr/include/libio.h" 3 4259 __off64_t _offset;260 # 302 "/usr/include/libio.h" 3 4261 void *__pad1;262 void *__pad2;263 void *__pad3;264 void *__pad4;265 size_t __pad5;266 267 int _mode;268 269 char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];270 271 };272 273 274 typedef struct _IO_FILE _IO_FILE;275 276 277 struct _IO_FILE_plus;278 279 extern struct _IO_FILE_plus _IO_2_1_stdin_;280 extern struct _IO_FILE_plus _IO_2_1_stdout_;281 extern struct _IO_FILE_plus _IO_2_1_stderr_;282 # 338 "/usr/include/libio.h" 3 4283 typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes);284 285 286 287 288 289 290 291 typedef __ssize_t __io_write_fn (void *__cookie, const char *__buf,292 size_t __n);293 294 295 296 297 298 299 300 typedef int __io_seek_fn (void *__cookie, __off64_t *__pos, int __w);301 302 303 typedef int __io_close_fn (void *__cookie);304 # 390 "/usr/include/libio.h" 3 4305 extern int __underflow (_IO_FILE *);306 extern int __uflow (_IO_FILE *);307 extern int __overflow (_IO_FILE *, int);308 # 434 "/usr/include/libio.h" 3 4309 extern int _IO_getc (_IO_FILE *__fp);310 extern int _IO_putc (int __c, _IO_FILE *__fp);311 extern int _IO_feof (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));312 extern int _IO_ferror (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));313 314 extern int _IO_peekc_locked (_IO_FILE *__fp);315 316 317 318 319 320 extern void _IO_flockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));321 extern void _IO_funlockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));322 extern int _IO_ftrylockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));323 # 464 "/usr/include/libio.h" 3 4324 extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict,325 __gnuc_va_list, int *__restrict);326 extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict,327 __gnuc_va_list);328 extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t);329 extern size_t _IO_sgetn (_IO_FILE *, void *, size_t);330 331 extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int);332 extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int);333 334 extern void _IO_free_backup_area (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));335 # 75 "/usr/include/stdio.h" 2 3 4336 337 338 339 340 typedef __gnuc_va_list va_list;341 # 90 "/usr/include/stdio.h" 3 4342 typedef __off_t off_t;343 # 102 "/usr/include/stdio.h" 3 4344 typedef __ssize_t ssize_t;345 346 347 348 349 350 351 352 typedef _G_fpos_t fpos_t;353 354 355 356 357 # 164 "/usr/include/stdio.h" 3 4358 # 1 "/usr/include/x86_64-linux-gnu/bits/stdio_lim.h" 1 3 4359 # 165 "/usr/include/stdio.h" 2 3 4360 361 362 363 extern struct _IO_FILE *stdin;364 extern struct _IO_FILE *stdout;365 extern struct _IO_FILE *stderr;366 367 368 369 370 371 372 373 extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__));374 375 extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__));376 377 378 379 380 extern int renameat (int __oldfd, const char *__old, int __newfd,381 const char *__new) __attribute__ ((__nothrow__ , __leaf__));382 383 384 385 386 387 388 389 390 extern FILE *tmpfile (void) ;391 # 209 "/usr/include/stdio.h" 3 4392 extern char *tmpnam (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;393 394 395 396 397 398 extern char *tmpnam_r (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;399 # 227 "/usr/include/stdio.h" 3 4400 extern char *tempnam (const char *__dir, const char *__pfx)401 __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) ;402 403 404 405 406 407 408 409 410 extern int fclose (FILE *__stream);411 412 413 414 415 extern int fflush (FILE *__stream);416 417 # 252 "/usr/include/stdio.h" 3 4418 extern int fflush_unlocked (FILE *__stream);419 # 266 "/usr/include/stdio.h" 3 4420 421 422 423 424 425 426 extern FILE *fopen (const char *__restrict __filename,427 const char *__restrict __modes) ;428 429 430 431 432 extern FILE *freopen (const char *__restrict __filename,433 const char *__restrict __modes,434 FILE *__restrict __stream) ;435 # 295 "/usr/include/stdio.h" 3 4436 437 # 306 "/usr/include/stdio.h" 3 4438 extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) ;439 # 319 "/usr/include/stdio.h" 3 4440 extern FILE *fmemopen (void *__s, size_t __len, const char *__modes)441 __attribute__ ((__nothrow__ , __leaf__)) ;442 443 444 445 446 extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) ;447 448 449 450 451 452 453 extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__));454 455 456 457 extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf,458 int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__));459 460 461 462 463 464 extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf,465 size_t __size) __attribute__ ((__nothrow__ , __leaf__));466 467 468 extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));469 470 471 472 473 474 475 476 477 extern int fprintf (FILE *__restrict __stream,478 const char *__restrict __format, ...);479 480 481 482 483 extern int printf (const char *__restrict __format, ...);484 485 extern int sprintf (char *__restrict __s,486 const char *__restrict __format, ...) __attribute__ ((__nothrow__));487 488 489 490 491 492 extern int vfprintf (FILE *__restrict __s, const char *__restrict __format,493 __gnuc_va_list __arg);494 495 496 497 498 extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg);499 500 extern int vsprintf (char *__restrict __s, const char *__restrict __format,501 __gnuc_va_list __arg) __attribute__ ((__nothrow__));502 503 504 505 506 507 extern int snprintf (char *__restrict __s, size_t __maxlen,508 const char *__restrict __format, ...)509 __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4)));510 511 extern int vsnprintf (char *__restrict __s, size_t __maxlen,512 const char *__restrict __format, __gnuc_va_list __arg)513 __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0)));514 515 # 412 "/usr/include/stdio.h" 3 4516 extern int vdprintf (int __fd, const char *__restrict __fmt,517 __gnuc_va_list __arg)518 __attribute__ ((__format__ (__printf__, 2, 0)));519 extern int dprintf (int __fd, const char *__restrict __fmt, ...)520 __attribute__ ((__format__ (__printf__, 2, 3)));521 522 523 524 525 526 527 528 529 extern int fscanf (FILE *__restrict __stream,530 const char *__restrict __format, ...) ;531 532 533 534 535 extern int scanf (const char *__restrict __format, ...) ;536 537 extern int sscanf (const char *__restrict __s,538 const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__));539 # 443 "/usr/include/stdio.h" 3 4540 extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf")541 542 ;543 extern int scanf (const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf")544 ;545 extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__))546 547 ;548 # 463 "/usr/include/stdio.h" 3 4549 550 551 552 553 554 555 556 557 extern int vfscanf (FILE *__restrict __s, const char *__restrict __format,558 __gnuc_va_list __arg)559 __attribute__ ((__format__ (__scanf__, 2, 0))) ;560 561 562 563 564 565 extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg)566 __attribute__ ((__format__ (__scanf__, 1, 0))) ;567 568 569 extern int vsscanf (const char *__restrict __s,570 const char *__restrict __format, __gnuc_va_list __arg)571 __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0)));572 # 494 "/usr/include/stdio.h" 3 4573 extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf")574 575 576 577 __attribute__ ((__format__ (__scanf__, 2, 0))) ;578 extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf")579 580 __attribute__ ((__format__ (__scanf__, 1, 0))) ;581 extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__))582 583 584 585 __attribute__ ((__format__ (__scanf__, 2, 0)));586 # 522 "/usr/include/stdio.h" 3 4587 588 589 590 591 592 593 594 595 596 extern int fgetc (FILE *__stream);597 extern int getc (FILE *__stream);598 599 600 601 602 603 extern int getchar (void);604 605 # 550 "/usr/include/stdio.h" 3 4606 extern int getc_unlocked (FILE *__stream);607 extern int getchar_unlocked (void);608 # 561 "/usr/include/stdio.h" 3 4609 extern int fgetc_unlocked (FILE *__stream);610 611 612 613 614 615 616 617 618 619 620 621 extern int fputc (int __c, FILE *__stream);622 extern int putc (int __c, FILE *__stream);623 624 625 626 627 628 extern int putchar (int __c);629 630 # 594 "/usr/include/stdio.h" 3 4631 extern int fputc_unlocked (int __c, FILE *__stream);632 633 634 635 636 637 638 639 extern int putc_unlocked (int __c, FILE *__stream);640 extern int putchar_unlocked (int __c);641 642 643 644 645 646 647 extern int getw (FILE *__stream);648 649 650 extern int putw (int __w, FILE *__stream);651 652 653 654 655 656 657 658 659 extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)660 ;661 # 638 "/usr/include/stdio.h" 3 4662 extern char *gets (char *__s) __attribute__ ((__deprecated__));663 664 665 # 665 "/usr/include/stdio.h" 3 4666 extern __ssize_t __getdelim (char **__restrict __lineptr,667 size_t *__restrict __n, int __delimiter,668 FILE *__restrict __stream) ;669 extern __ssize_t getdelim (char **__restrict __lineptr,670 size_t *__restrict __n, int __delimiter,671 FILE *__restrict __stream) ;672 673 674 675 676 677 678 679 extern __ssize_t getline (char **__restrict __lineptr,680 size_t *__restrict __n,681 FILE *__restrict __stream) ;682 683 684 685 686 687 688 689 690 extern int fputs (const char *__restrict __s, FILE *__restrict __stream);691 692 693 694 695 696 extern int puts (const char *__s);697 698 699 700 701 702 703 extern int ungetc (int __c, FILE *__stream);704 705 706 707 708 709 710 extern size_t fread (void *__restrict __ptr, size_t __size,711 size_t __n, FILE *__restrict __stream) ;712 713 714 715 716 extern size_t fwrite (const void *__restrict __ptr, size_t __size,717 size_t __n, FILE *__restrict __s);718 719 # 737 "/usr/include/stdio.h" 3 4720 extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,721 size_t __n, FILE *__restrict __stream) ;722 extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size,723 size_t __n, FILE *__restrict __stream);724 725 726 727 728 729 730 731 732 extern int fseek (FILE *__stream, long int __off, int __whence);733 734 735 736 737 extern long int ftell (FILE *__stream) ;738 739 740 741 742 extern void rewind (FILE *__stream);743 744 # 773 "/usr/include/stdio.h" 3 4745 extern int fseeko (FILE *__stream, __off_t __off, int __whence);746 747 748 749 750 extern __off_t ftello (FILE *__stream) ;751 # 792 "/usr/include/stdio.h" 3 4752 753 754 755 756 757 758 extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos);759 760 761 762 763 extern int fsetpos (FILE *__stream, const fpos_t *__pos);764 # 815 "/usr/include/stdio.h" 3 4765 766 # 824 "/usr/include/stdio.h" 3 4767 768 769 extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));770 771 extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;772 773 extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;774 775 776 777 778 extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));779 extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;780 extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;781 782 783 784 785 786 787 788 789 extern void perror (const char *__s);790 791 792 793 794 795 796 # 1 "/usr/include/x86_64-linux-gnu/bits/sys_errlist.h" 1 3 4797 # 26 "/usr/include/x86_64-linux-gnu/bits/sys_errlist.h" 3 4798 extern int sys_nerr;799 extern const char *const sys_errlist[];800 # 854 "/usr/include/stdio.h" 2 3 4801 802 803 804 805 extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;806 807 808 809 810 extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;811 # 873 "/usr/include/stdio.h" 3 4812 extern FILE *popen (const char *__command, const char *__modes) ;813 814 815 816 817 818 extern int pclose (FILE *__stream);819 820 821 822 823 824 extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));825 # 913 "/usr/include/stdio.h" 3 4826 extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));827 828 829 830 extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;831 832 833 extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));834 # 943 "/usr/include/stdio.h" 3 4835 836 # 2 "hello.c" 2837 int main()838 {839 printf("hello world!\n");840 return 0;841 842 }
我们编写的hello world的源代码 实际上就在hello.i 这个文件的最后面。
到这里 我们就大致明白了预编译的作用和功能了。(实际上大家可以把自己的工程 用这个命令生成一下预编译文件,看看里面是什么内容。)
具体文字化的预编译含义,大家可以自行百度。 我就不复制粘贴了。
然后第二步编译的过程,实际上就是把我们的预处理完的文件 进行一系列语法分析 词法分析 等等一系列复杂的工作以后生成的汇编代码文件。
这个编译的过程,就是程序build过程里面最复杂的部分了。
有了我们的预处理文件 生成汇编代码文件的命令就是:
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_startproc11 pushq %rbp12 .cfi_def_cfa_offset 1613 .cfi_offset 6, -1614 movq %rsp, %rbp15 .cfi_def_cfa_register 616 movl $.LC0, %edi17 call puts18 movl $0, %eax19 popq %rbp20 .cfi_def_cfa 7, 821 ret22 .cfi_endproc23 .LFE0:24 .size main, .-main25 .ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"26 .section .note.GNU-stack,"",@progbits
到这里实际上我们已经能看出来,gcc 这个命令只是这些后台程序的包装,他会根据不同的参数去调用预编译程序 ,汇编器,和链接器。
得到汇编源代码文件以后 我们就去汇编他。
输入命令
gcc -c hello.s -o hello.o
很显然这个.o文件我们cat以后是乱码。
最后讲讲链接
写程序的时候,我们都知道 一个很复杂的工程,我们会把它分解成若干很小的工程,然后把这些很小的工程分解成一个个若干的模块。
最终每个功能都对应着一个文件或者若干个文件。
最终这些文件 都各自对应着一个 目标文件 也就是.o文件。但是最终我们只需要一个可执行文件对吧。而且这些.o文件之间还要互相通信,
模块间的函数调用,以及模块间的变量访问。
所谓的链接,linking,就是这些模块的拼接过程。
这个链接的工程 主要是 地址和空间分配,符号决议,和重定位这些步骤。
最基本的静态链接过程就是把我们的目标文件和库一起链接成最终的可执行文件。
最常见的库就是runtime library 。这是支持程序运行的最基本的库的集合,实际上就是一组目标文件的包,把常用的代码编程目标文件 后打包存放。
hello world的本质-----预编译,编译,汇编,链接