💻实验0-2:vim+gcc

实验2-参考文档

写在前面:

  • 实验2的详细要求见 ppt 最后一页!!!

  • 这个文档只是一个参考,请同学们在完成实验报告时要写的尽量详细,并且按照实验报告模板规范书写。

  • 重要的事情说三遍 善用搜索引擎!善用搜索引擎!善用搜索引擎!很多问题先自己尝试解决!

Vim常用命令指南

Vim 的基本概念

基本上 vim 可以分为三种状态,分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下:

  1. 命令行模式(command mode) 控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode。

  2. 插入模式(Insert mode) 只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。

  3. 底行模式(last line mode) 将文件保存或退出 vim ,也可以设置编辑环境,如寻找字符串、列出行号……等。

不过一般我们在使用时把 vim 简化成两个模式,就是将底行模式(last line mode)也算入命令行模式command mode)。

Vim 的基本操作

a.进入 vim

输入 vim <file> 就可以打开文件 file 以进入 vim 编辑器;

不过有一点要特别注意,就是您进入 vim 之后,是处于「命令模式(command mode)」,您要切换到「插入模式(Insert mode)」才能够输入文字。

b.切换至插入模式

在「命令行模式(command mode)」下按一下字母(ioaIOA任意一个)就可以进入「插入模式(Insert mode)」,这时候你就可以开始输入文字了。

i是在光标所在的字符之前插入需要录入的文本。

I 是在光标所在行的行首插入需要录入的文本。

a 是在光标所在的字符之后插入需要录入的文本。

A 是在光标所在行的行尾插入需要录入的文本。

o 是光标所在行的下一行行首插入需要录入的文本。

O 是光标所在行的上一行行首插入需要录入的文本。

s 删除光标所在处的字符然后插入需要录入的文本。

S 删除光标所在行,在当前行的行首开始插入需要录入的文本。

VIM 删除多行文本

:n1,n2d

n1n2指的是起始行号和结束行号,d 是删除关键字

c.跳到文件中的某一行

「:#」:#号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行。

d.查找字符

  • /关键字」:先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止,「N」会向前寻找。

  • ?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往前寻找到您要的关键字为止,「N」会向后寻找。

e.保存文件

  • :w」:可以将文件保存起来。

f. 离开 Vim

  • :q」:退出但不保存,如果无法离开,可以在「q」后跟一个「!」强制离开vi。

  • :wq」:退出并保存。

vim还有非常多其他的操作,请同学们自行学习

除了vim外 还有许多代码编辑器 总之有多种选择 善用搜索引擎 自行探索选择。

gcc编译

1. GCC编译c/c++一步完成

“编译”C、C++ 程序,其本意指的是将 C、C++ 代码转变为可执行程序(等同于 Windows 系统中以 .exe 为后缀的可执行文件)C 或者 C++ 程序从源代码生成可执行程序的过程,需经历 4 个过程,分别是预处理、编译、汇编和链接

使用 GCC 编译器编译 C 或者 C++ 程序,也必须要经历这 4 个过程。但考虑在实际使用中,用户可能并不关心程序的执行结果,只想快速得到最终的可执行程序,因此 gcc 和 g++ 都对此需求做了支持。

使用 gcc 快速获得对应的可执行程序:(针对简单的c语言 'helloworld.c' 文件)

执行:

gcc xxx.c

gcc编译器就会在当前目录下生成对应的可执行文件a.out文件

执行./a.out可以查看运行结果。

gcc 指令还支持用户手动指定最终生成的可执行文件的文件名

gcc xxx.c -o xxxx

-o 选项用于指定要生成的文件名,例如 -o helloworld 即表示将生成的可执行文件的文件名设为 helloworld。

虽然仅编写了一条 gcc 指令,但其底层依据是按照预处理、编译、汇编、链接的过程将 C 、C++ 程序转变为可执行程序的。而本应在预处理阶段、编译阶段、汇编阶段生成的中间文件,此执行方式默认是不会生成的,只会生成最终的 a.out 可执行文件。

2. “分步编译”

深入探究 C、C++ 程序转变为可执行程序的整个过程,查看该过程中产生的中间文件。如此,上面介绍的执行方式将不再使用,而要采用分步编译的方式。

即由用户手动调用 GCC 编译器完成对 C、C++源代码的预处理、编译、汇编以及链接过程,每个阶段都会生成对源代码加工后的文件。

gcc指令选项

功 能

-E(大写)

预处理指定的源文件,不进行编译。

-S(大写)

编译指定的源文件,但是不进行汇编。

-c

编译、汇编指定的源文件,但是不进行链接。

-o

指定生成文件的文件名。

gcc -E 指令只会将预处理操作的结果输出到屏幕上,并不会自动保存到某个文件。

因此该指令往往会和 -o 选项连用,将结果导入到指令的文件中。比如:

gcc -E xxxx.c -o xxx.i

Linux 系统中通常用 ".i" 作为 C 语言程序预处理后所得文件的后缀名。

由此,就完成了 helloworld.c 文件的预处理操作,并将其结果导入到了 demo.i 文件中。

然后我们使用指令:

cat demo.i

查看该文件中的内容,但通常没有足够 C 语言功底是看不懂的。为此,我们可以为 gcc 指令再添加一个 -C 选项,阻止 GCC 删除源文件和头文件中的注释

gcc -E -C xxxx.c -o xxxx.i  ##注意此处-C大写

gcc -S指令对已得到的预处理文件进行编译

gcc -S demo.i

可以看到,经过执行 gcc -S 指令,其生成了一个名为 demo.s 的文件,这就是经过编译的汇编代码文件。也就是说默认情况下,编译操作会自行新建一个文件名和指定文件相同、后缀名为 .s 的文件,并将编译的结果保存在该文件中。

当然我们还可以为 gcc -S 指令添加 -o 选项,令 GCC 编译器将编译结果保存在我们指定的文件中。

需要注意的是,gcc -S 指令操作的文件并非必须是经过预处理后得到的 .i 文件,-S 选项的功能是令 GCC 编译器将指定文件处理至编译阶段结束。这也就意味着,gcc -S 指令可以操作预处理后的 .i 文件,也可以操作源代码文件:

  • 如果操作对象为 .i 文件,则 GCC 编译器只需编译此文件;

  • 如果操作对象为 .c 或者 .cpp 源代码文件,则 GCC 编译器会对其进行预处理和编译这 2 步操作。

因此,如果我们想直接得到 xxx.c 文件对应的汇编文件,就可以借助 gcc -S 指令:

gcc -S xxx.c -o xxx.s

gcc-c指令 汇编 生成目标文件。

汇编其实就是将汇编代码转换成可以执行的机器指令。大部分汇编语句对应一条机器指令,有的汇编语句对应多条机器指令。相对于编译操作,汇编过程会简单很多,它并没有复杂的语法,也没有语义,也不需要做指令优化,只需要根据汇编语句和机器指令的对照表一一翻译即可

通过为 gcc 指令添加 -c 选项(注意是小写字母 c),即可让 GCC 编译器将指定文件加工至汇编阶段,并生成相应的目标文件。

gcc -c xxx.s

该指令会生成和 xxx.s 同名但后缀名为 .o 的文件,这就是经过汇编操作得到的目标文件。

注:-o 命令同样是可以保存在指定文件中。(正常来说不加参数生成的是wang.o 加了参数生成的是wang2.o)

需要强调的一点是,和 gcc -S 类似,gcc -c 选项并非只能用于加工 .s 文件。事实上,-c 选项只是令 GCC 编译器将指定文件加工至汇编阶段,但不执行链接操作。这也就意味着:

  • 如果指定文件为源程序文件(例如 demo.c),则 gcc -c 指令会对 demo.c 文件执行预处理、编译以及汇编这 3 步操作;

  • 如果指定文件为刚刚经过预处理后的文件(例如 demo.i),则 gcc -c 指令对 demo.i 文件执行编译和汇编这 2 步操作;

  • 如果指定文件为刚刚经过编译后的文件(例如 demo.s),则 gcc -c 指令只对 demo.s 文件执行汇编这 1 步操作。

注意,如果指定文件已经经过汇编,或者 GCC 编译器无法识别,则 gcc -c 指令不做任何操作。

###依次实验:
gcc -c xxx.c -o xxx1.o
ls
gcc -c xxx.i -o xxx2.o
ls
gcc -c xxx.s -o xxx3.o
ls

得到生成目标文件之后,接下来就可以直接使用 gcc 指令继续执行链接操作。

 gcc xxx.o -o xxx
 ./xxx

make编译

make 命令是GNU的工程化编译工具,用于编译众多相互关联的源代码,以实现工程化的管理,提高开发效率。

有一些比较复杂的软件,不仅有一支程序,而是一堆的程序代码文件,在编译过程中,除了每个主程序与子程序均需要写上一笔编译过程的指令外,还需要写上最终的链接程序,这个时候就可以使用 make 这个指令的相关功能来进行编译过程的指令简化了。

当执行 make 时,make 会在当时的目录下搜寻 Makefile (or makefile) 这个文本文件,而 Makefile里面则记录了原始码如何编译的详细信息!make 会自动的判别原始码是否经过变动了,而自动更新执行档。

说明:

本学期后续所有的lab都是在 cmu 已经搭建好的“平台”上进行的:一般每个实验相应的材料压缩包中都已经包括 makefile 等文件,这个不需要自己更改!!大家可以简单将其理解为是用来编译测试的工具。本节课上面讲的有关编译内容是在告诉同学们这部分的原理。

后续每个lab都会有相应的任务要完成,完成后大家只需要借助make工具,直接编译运行,“平台”的自动打分系统会帮助你们评分,测试任务完成情况。

Last updated