[{"content":" 我觉得程序员这个群体是非常幸运的一群人，我们生在一个技术改变世界的时代，而我们可能正做着能够改变世界的技术，这是何等的荣耀和机遇。 ——《MacTalk 人生元编程》\n前言 大概每个程序员在开篇都会写一个 Hello World! 来作为开始。这是我的第一篇博客，就来写一写程序员眼中的 Hello World!。\n这是一个 01 的世界 每个伟大的梦想都来自最小的尝试。秒写一个代码：hello.c\n#include \u0026lt;stdio.h\u0026gt; int main() { printf(\u0026#34;Hello world\\n\u0026#34;); return 0; } 这段代码相信大家都很熟悉，无非就是输出一个 Hello world 字符串。下面我们就来分析一下这段代码。\n预处理阶段 我们可以使用 gcc -E hello.c -o hello.i 来将预处理之后的数据存到 hello.i 中，或者使用 \u0026gt; 重定向到指定的文件，预处理的结果比较简单，大家可以直接看输出的结果。\n编译阶段 gcc -S hello.i -o hello.s 将预处理之后的文件编译成 hello.s 文件。 在编译阶段，编译器检查代码的规范性、是否有语法错误等，在检查无误后，gcc 把代码翻译成汇编语言。 我们来看一下编译之后的文件 \u0026gt;more hello.s\n.file\t\u0026#34;hello.c\u0026#34; .section\t.rodata .LC0: .string\t\u0026#34;Hello world\u0026#34; .text .globl\tmain .type\tmain, @function main: .LFB0: .cfi_startproc pushq\t%rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq\t%rsp, %rbp .cfi_def_cfa_register 6 movl\t$.LC0, %edi call\tputs movl\t$0, %eax popq\t%rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size\tmain, .-main .ident\t\u0026#34;GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2\u0026#34; .section\t.note.GNU-stack,\u0026#34;\u0026#34;,@progbits 汇编阶段 汇编阶段将编译阶段生成的.s 文件转成二进制目标代码。 gcc -c hello.s -o hello.o 生成了.o 二进制文件，这时就不能使用 more 来进行文本查看了，可以使用 objdump 命令。 objdump -d hello.o\nhello.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 \u0026lt;main\u0026gt;: 0:\t55 push %rbp 1:\t48 89 e5 mov %rsp,%rbp 4:\tbf 00 00 00 00 mov $0x0,%edi 9:\te8 00 00 00 00 callq e \u0026lt;main+0xe\u0026gt; e:\tb8 00 00 00 00 mov $0x0,%eax 13:\t5d pop %rbp 14:\tc3 retq 我们可以看到，main 函数的汇编代码。\n链接阶段 最后就是链接啦，将.o 文件链接成可执行文件 gcc hello.o -o hello ，我们仍然使用 objdump 命令来查看 hello 文件 objdump -d hello 输出比较长，我们截取 main 函数的部分来看。\n000000000040052d \u0026lt;main\u0026gt;: 40052d:\t55 push %rbp 40052e:\t48 89 e5 mov %rsp,%rbp 400531:\tbf d4 05 40 00 mov $0x4005d4,%edi 400536:\te8 d5 fe ff ff callq 400410 \u0026lt;puts@plt\u0026gt; 40053b:\tb8 00 00 00 00 mov $0x0,%eax 400540:\t5d pop %rbp 400541:\tc3 retq 400542:\t66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 400549:\t00 00 00 40054c:\t0f 1f 40 00 nopl 0x0(%rax) 最后执行\n\u0026gt;./hello Hello world 到现在我们只是从一个 Hello World 程序的输出结果走马观花了一下程序运行的过程，对于过程中的每一个文件分析并没有写出，算是留一点神秘感吧，从程序数据组织，包括代码段、数据段等，到汇编代码的底层实现，计算机有着太多的东西让我们去发现和思考。\n正如开头所说，生在这样的一个时代是非常幸运的。但行好事，莫问前程，出发！\nPost author: JontyWang\nPost link: https://jonty.top/2021/08/05/hello-world/\nCopyright Notice: All articles in this blog are licensed under BY-NC-SA unless stating additionally.\n","permalink":"https://leafcxy.github.io/posts/hello-world/","summary":"\u003cblockquote\u003e\n\u003cp\u003e我觉得程序员这个群体是非常幸运的一群人，我们生在一个技术改变世界的时代，而我们可能正做着能够改变世界的技术，这是何等的荣耀和机遇。 ——《MacTalk 人生元编程》\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e大概每个程序员在开篇都会写一个 Hello World! 来作为开始。这是我的第一篇博客，就来写一写程序员眼中的 Hello World!。\u003c/p\u003e\n\u003c!-- more --\u003e\n\u003ch2 id=\"这是一个-01-的世界\"\u003e这是一个 01 的世界\u003c/h2\u003e\n\u003cp\u003e每个伟大的梦想都来自最小的尝试。秒写一个代码：hello.c\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e#include\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003eint\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003emain\u003c/span\u003e()\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#a6e22e\"\u003eprintf\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Hello world\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e\\n\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u003c/span\u003e);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#66d9ef\"\u003ereturn\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这段代码相信大家都很熟悉，无非就是输出一个 Hello world 字符串。下面我们就来分析一下这段代码。\u003c/p\u003e\n\u003ch2 id=\"预处理阶段\"\u003e预处理阶段\u003c/h2\u003e\n\u003cp\u003e我们可以使用 gcc -E hello.c -o hello.i 来将预处理之后的数据存到 hello.i 中，或者使用 \u0026gt; 重定向到指定的文件，预处理的结果比较简单，大家可以直接看输出的结果。\u003c/p\u003e\n\u003ch2 id=\"编译阶段\"\u003e编译阶段\u003c/h2\u003e\n\u003cp\u003egcc -S hello.i -o hello.s 将预处理之后的文件编译成 hello.s 文件。\n在编译阶段，编译器检查代码的规范性、是否有语法错误等，在检查无误后，gcc 把代码翻译成汇编语言。 我们来看一下编译之后的文件 \u0026gt;more hello.s\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e    .file\t\u0026#34;hello.c\u0026#34;\n.section\t.rodata\n.LC0:\n    .string\t\u0026#34;Hello world\u0026#34;\n    .text\n    .globl\tmain\n    .type\tmain, @function\nmain:\n.LFB0:\n    .cfi_startproc\n    pushq\t%rbp\n    .cfi_def_cfa_offset 16\n    .cfi_offset 6, -16\n    movq\t%rsp, %rbp\n    .cfi_def_cfa_register 6\n    movl\t$.LC0, %edi\n    call\tputs\n    movl\t$0, %eax\n    popq\t%rbp\n    .cfi_def_cfa 7, 8\n    ret\n    .cfi_endproc\n.LFE0:\n    .size\tmain, .-main\n    .ident\t\u0026#34;GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2\u0026#34;\n    .section\t.note.GNU-stack,\u0026#34;\u0026#34;,@progbits\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"汇编阶段\"\u003e汇编阶段\u003c/h2\u003e\n\u003cp\u003e汇编阶段将编译阶段生成的.s 文件转成二进制目标代码。 gcc -c hello.s -o hello.o 生成了.o 二进制文件，这时就不能使用 more 来进行文本查看了，可以使用 objdump 命令。 objdump -d hello.o\u003c/p\u003e","title":"Hello World"}]