各大编程语言经典的开始都是 hello world. 起源就不用说了(可以网上查到)。透过该简单的程序,我们应该从中知道些什么讯息,这是我们需要了解和掌握的。
先看一下 C 语言中, hello world 的代码吧:
#include <stdio.h> int main() { printf("Hello world!\n"); return 0; }
代码本身比较简单,主体只有一句:
printf("Hello world!\n");
这句话的作用就是在屏幕上打印出一句"hello world!".
我们来看一下 windows 和 Linux 中的运行结果吧:
windows 在控制台中输出了我们期待的结果,linux 也在终端中输出了字符串。到此,hello world 的主体功能结束。
接下来我们逐行分析一下hello world 的代码。
Line#1: #include <stdio.h>
这一句称为预处理,编译过程中称为预编译(pre-compile)。这句话的作用是将 stdio.h 中的代码块复制到代码文件的 #include 处。如果我们不加这一句,编译的时候会出现printf函数未定义的错误(警告)。编译器不同结果不同
gcc 会自动找到一些build-in 的函数,看起来这个程序能正常编译,但是会有隐患(如果自定义了同名函数,结果可能不是我们期待的,后续的博客中会说明)
我们看一下预编译后的结果:
...................... ...................... #line 723 "c:\\program files (x86)\\microsoft visual studio 11.0\\vc\\include\\stdio.h" #pragma pack(pop) #line 727 "c:\\program files (x86)\\microsoft visual studio 11.0\\vc\\include\\stdio.h" #line 2 "c:\\kylin\\consoleapplication1\\source.cpp" int main() { printf("Hello world!\n"); return 0; }
在main 函数之前,插入了一些代码块,这些都是由 stdio.h 文件带入
在gcc 中,插入类似的代码块
................ extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); # 943 "/usr/include/stdio.h" 3 4 # 2 "hello.c" 2 int main() { printf("Hello world!\n"); }
第二行代码是函数入口 main 函数。C 和 C++ 应用程序入口都是 main 函数,代码中也应该只有一个main函数。可以在main函数中定义参数。
printf 是 stdio.h 中提供的C库函数,用来打印到屏幕上。
hello world 后跟的 "\n",是换行符,如果不加的话,打印结束后不会换行。
简单的 hello world 程序,实际包含了C/C++ 的几个编译相关问题:
- 预处理
- 编译
- 汇编
- 链接
下边几个代码如果不感兴趣,可以不用打开。
后续会有更精彩的博文。
因为gcc更灵活,使用gcc的代码块来示例。
当我们使用 gcc -S 参数时,生成汇编前的编译结果如下:
.file "hello.c" .section .rodata .LC0: .string "Hello world!" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $.LC0, %edi call puts popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)" .section .note.GNU-stack,"",@progbits
当使用 gcc -c 参数时,生成link前的代码如下:
^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^A^@>^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@<98>^B^@^@^@^@^@^@^@^@^@^@@^@^@^@^@^@@^@^M^@^L^@UH<89>å¿^@^@^@^@è^@^@^@^@]ÃHello world!^@^@GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)^@^@^@^@^@^@^T^@^@^@^@^@^@^@^AzR^@^Ax^P^A^[^L^G^H<90>^A^@^@^\^@^@^@^\^@^@^@^@^@^@^@^P^@^@^@^@A^N^P<86>^BC^M^FK^L^G^H^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^D^@ñÿ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^C^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^D^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^E^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^G^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^H^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^F^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^R^@^A^@^@^@^@^@^@^@^@^@^P^@^@^@^@^@^@^@^N^@^@^@^P^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@hello.c^@main^@puts^@^@^@^@^@^@^E^@^@^@^@^@^@^@ ^@^@^@^E^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^@^@^@^@^B^@^@^@ ^@^@^@üÿÿÿÿÿÿÿ ^@^@^@^@^@^@^@^B^@^@^@^B^@^@^@^@^@^@^@^@^@^@^@^@.symtab^@.strtab^@.shstrtab^@.rela.text^@.data^@.bss^@.rodata^@.comment^@.note.GNU-stack^@.rela.eh_frame^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^A^@^@^@^F^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@@^@^@^@^@^@^@^@^P^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^[^@^@^@^D^@^@^@@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@è^A^@^@^@^@^@^@0^@^@^@^@^@^@^@ ^@^@^@^A^@^@^@^H^@^@^@^@^@^@^@^X^@^@^@^@^@^@^@&^@^@^@^A^@^@^@^C^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@P^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@,^@^@^@^H^@^@^@^C^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@P^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@1^@^@^@^A^@^@^@^B^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@P^@^@^@^@^@^@^@^M^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@9^@^@^@^A^@^@^@0^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@]^@^@^@^@^@^@^@.^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@B^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@<8b>^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@W^@^@^@^A^@^@^@^B^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@<90>^@^@^@^@^@^@^@8^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^H^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@R^@^@^@^D^@^@^@@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^X^B^@^@^@^@^@^@^X^@^@^@^@^@^@^@ ^@^@^@^H^@^@^@^H^@^@^@^@^@^@^@^X^@^@^@^@^@^@^@^A^@^@^@^B^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@È^@^@^@^@^@^@^@^H^A^@^@^@^@^@^@^K^@^@^@ ^@^@^@^H^@^@^@^@^@^@^@^X^@^@^@^@^@^@^@ ^@^@^@^C^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@Ð^A^@^@^@^@^@^@^S^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^Q^@^@^@^C^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@0^B^@^@^@^@^@^@a^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
生成的可执行文件:
^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^B^@>^@^A^@^@^@0^D@^@^@^@^@^@@^@^@^@^@^@^@^@8^Y^@^@^@^@^@^@^@^@^@^@@^@8^@ ^@@^@^_^@^^^@^F^@^@^@^E^@^@^@@^@^@^@^@^@^@^@@^@@^@^@^@^@^@@^@@^@^@^@^@^@ø^A^@^@^@^@^@^@ø^A^@^@^@^@^@^@^H^@^@^@^@^@^@^@^C^@^@^@^D^@^@^@8^B^@^@^@^@^@^@8^B@^@^@^@^@^@8^B@^@^@^@^@^@^\^@^@^@^@^@^@^@^\^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^A^@^@^@^E^@^@^@^@^@^@^@^@^@^@^@^@^@@^@^@^@^@^@^@^@@^@^@^@^@^@ü^F^@^@^@^@^@^@ü^F^@^@^@^@^@^@^@^@ ^@^@^@^@^@^A^@^@^@^F^@^@^@^P^N^@^@^@^@^@^@^P^N`^@^@^@^@^@^P^N`^@^@^@^@^@^\^B^@^@^@^@^@^@ ^B^@^@^@^@^@^@^@^@ ^@^@^@^@^@^B^@^@^@^F^@^@^@(^N^@^@^@^@^@^@(^N`^@^@^@^@^@(^N`^@^@^@^@^@Ð^A^@^@^@^@^@^@Ð^A^@^@^@^@^@^@^H^@^@^@^@^@^@^@^D^@^@^@^D^@^@^@T^B^@^@^@^@^@^@T^B@^@^@^@^@^@T^B@^@^@^@^@^@D^@^@^@^@^@^@^@D^@^@^@^@^@^@^@^D^@^@^@^@^@^@^@Påtd^D^@^@^@Ð^E^@^@^@^@^@^@Ð^E@^@^@^@^@^@Ð^E@^@^@^@^@^@4^@^@^@^@^@^@^@4^@^@^@^@^@^@^@^D^@^@^@^@^@^@^@Qåtd^F^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^P^@^@^@^@^@^@^@Råtd^D^@^@^@^P^N^@^@^@^@^@^@^P^N`^@^@^@^@^@^P^N`^@^@^@^@^@ð^A^@^@^@^@^@^@ð^A^@^@^@^@^@^@^A^@^@^@^@^@^@^@/lib64/ld-linux-x86-64.so.2^@^D^@^@^@^P^@^@^@^A^@^@^@GNU^@^@^@^@^@^B^@^@^@^F^@^@^@ ^@^@^@^D^@^@^@^T^@^@^@^C^@^@^@GNU^@^Unió<9e>^^Nc<8e>D<88>:gÐ^U^S^XA<8c><9e>^A^@^@^@^A^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^K^@^@^@^R^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^P^@^@^@^R^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@"^@^@^@ ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@libc.so.6^@puts^@__libc_start_main^@__gmon_start__^@GLIBC_2.2.5^@^@^@^@^B^@^B^@^@^@^@^@^A^@^A^@^A^@^@^@^P^@^@^@^@^@^@^@u^Zi ^@^@^B^@1^@^@^@^@^@^@^@ø^O`^@^@^@^@^@^F^@^@^@^C^@^@^@^@^@^@^@^@^@^@^@^X^P`^@^@^@^@^@^G^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@ ^P`^@^@^@^@^@^G^@^@^@^B^@^@^@^@^@^@^@^@^@^@^@H<83>ì^HH<8b>^E%^L ^@H<85>Àt^EèC^@^@^@H<83>Ä^HÃ^@^@^@^@^@^@^@^@^@^@^@^@^@^@ÿ5^R^L ^@ÿ%^T^L ^@^O^_@^@ÿ%^R^L ^@h^@^@^@^@éàÿÿÿÿ%