【读图学C语言】编译时发生了什么?第1周

JING-TIME 教育无边界字幕组蛮拼组员 2014-11-19 21:35

一、你知道编译的时候发生了什么吗?

你知道C语言编译时发生了什么吗?

是不是像我一样嫌弃老师上课讲的冗长又抽象,搞什么嘛!

说那么多还不如把细节展示给我看!

这周的Shorts视频中有一集叫做Compilers,7分钟不仅详细讲了编译时的四个步骤,还打开查看了 -E -S -c之后的文件。看完感到极大的满足,于是动手试了一遍,下面把视频转换成图文,跟我一起学C语言啦!

首先,写一个大家非常熟悉的"hello world!"代码

哦,我用的编辑器是emacs,操作系统是ubuntu(linux),然后直接在终端(Terminal)下用gcc编译,然后 ./a.out 执行。运行正常

这就完成了一次编译到运行的操作。平时我做作业也都是这样,并没有理会从C语言到机器语言的编译过程具体是什么样。

二、编译的四个步骤

gcc的编译流程分为四个步骤,分别为:

・ 预处理(Pre-Processing)
・ 编译(Compiling)
・ 汇编(Assembling)
・ 链接(Linking)

(1)编译预处理(Pre-Processing)

先输入这一行命令:gcc -E 目标文件.c

回车后就被刷屏了....

把这些代码导入到一个hello2.c的文件中

打开后

这是什么鬼!长这么奇怪= =

哈,居然有800多行,拉到最后终于看到熟悉的 "hello world!"代码片段惹!

这就是编译预处理啦~ 搜了一下什么是编译预处理

【摘】预编译的主要作用如下:

●将源文件中以”include”格式包含的文件复制到编译的源文件中。
●用实际值替换用“#define”定义的字符串。
●根据“#if”后面的条件决定需要编译的代码。

是嘛~刚刚刷屏那个就是把源代码中 #include <stdio.h> 这一行替换成了834行代码..

再拿宏定义试试,注意第3行

相同操作之后,对比预处理之后的.c文件

喏,836行之前没有区别!只有原来 #define name "Jenny" 那一行消失了,取而代之的是源代码中 printf("Hello %s\n",name); 中的name 被换成了 "Jenny" 

这就是传说中的,define只做“文本替换”啦

(2)编译(Compiling)

下面用 gcc -S 目标文件.c 来编译,用C语言代码 生成 汇编语言

打开编译后的 hello.s 文件

又是什么鬼,完全看不懂....

(3)汇编(Assembling)

用 gcc -c 目标文件.s 把

打开 hello.o二进制文件

这就是传说中的机器码了,你看到中间的 "hello world!" 了吗?

*Bonus 直接修改二进制文件

让我们改改机器码试试!→_→

改成 no zuo no die ....

运行试试

玩坏了 ..>_<.. 一定是字节不一样!!

改成hello jenny

这样就行啦!

*Bonus 用十六进制看机器码!

哈哈哈,有点像传说中的10101010串了吧!我不知道怎么通过二进制查看机器码....

再改成nozuonodie!!

这次成功了

(4) 链接(Linking)

刚刚一直到这个步骤,其实代码都不能执行。可执行文件 a.out 是我之前一步gcc hello.c生成的。

最后一步链接,需要在二进制文件 hello.o 的基础上,生成可执行文件 .out 

命令为 gcc hello.o

列出当前文件夹下面的文件,可以发现只有 hello.out 是绿色的,并且最左边一堆rwx里面只有hello.out带有x,那些rwx表示的是"read","write","execute"的权限啦!

所有评论(15)

  • cuihao 1楼
    cuihao

    (´・ω・`) 我用 Windows 记事本打开 hello.o 改了一下机器码,保存之后怎么没法链接啊:

    $ gcc hello.o
    /usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld:hello.o: file format not recognized; treating as linker script
    /usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld:hello.o:1: syntax error
    collect2: 错误:ld 返回 1

    2014-11-20 08:52 举报
  • cuihao 2楼
    cuihao

    我机智地编译过的 .o 文件中的字符串改长成功了!赶脚那一坨 \@ 没啥用的样子,我就加一个字符然后从后面删除一个 \@ ~

    2014-11-20 09:10 举报
  • 北柒星 3楼
    北柒星

    楼上,二进制文件是不能用文本编辑器来改的吧。要用个bz.exe的软件来改

    2014-11-20 17:06 举报
  • chenwei 4楼
    chenwei MOOC学院演讲安利员

    看不懂。。

    2014-11-21 00:43 举报
  • 已退休少先队员 5楼
    已退休少先队员

    我大ubuntu威武!

    2014-11-21 18:27 举报
  • 一时不到 6楼
    一时不到

    虽然很想懂,但是就是不懂啊

    2014-11-22 09:38 举报
  • VinciLau 7楼
    VinciLau

    学习了

    2014-11-22 09:44 举报
  • 尚宗 8楼
    尚宗

    看到这些图,就想起了我奋斗的时候……这才几年呀,物是人非……

    2014-11-22 12:26 举报
  • 5523协会 9楼
    5523协会

    学习了,高大上的编译

    2014-11-22 20:15 举报
  • 张凯能 10楼
    张凯能

    收下了

    2014-11-23 20:55 举报
课程全部笔记
Introduction to Computer Science

Introduction to Computer Science计算机科学导论

评分:
9 (27人评价)
时间:
时间自主
难度:
一般

京ICP证100430号    京网文[2015] 0609-239号    新出发京零字东150005号     京公网安备11010502007133号 ©2017果壳网

关于我们 新手指南