1. 首先进入vi编辑器,查看源码

vi是一个编辑器

vi编辑器是一款在类Unix系统中广泛使用的文本编辑器。它由Bill Joy在1976年开发,至今仍然是许多程序员和系统管理员喜爱的工具。以下是vi编辑器的一些主要特点:

  1. 模式化编辑:vi编辑器有几种不同的模式,包括命令模式、插入模式和末行模式。这些模式使得vi在文本编辑时非常高效。

  • 命令模式:启动vi后默认进入命令模式,可以执行复制、粘贴、删除、移动光标等操作。

  • 插入模式:在命令模式下按iao等键可以进入插入模式,此时可以输入文本。

  • 末行模式:在命令模式下输入:可以进入末行模式,可以执行保存文件、退出编辑器、搜索替换等操作。

  1. 可扩展性:vi有一个更现代化的版本,称为Vim(Vi Improved),它提供了更多功能和插件支持,使得vi编辑器更加强大。

  2. 跨平台:vi编辑器几乎在所有的Unix和Linux系统中都可用,许多macOS和Windows版本也有相应的移植版本。

  3. 键盘操作为主:vi编辑器的设计理念是尽量减少鼠标操作,大部分操作都可以通过键盘完成,这提高了编辑效率。 以下是一些基本的vi操作命令:

  • i:进入插入模式,在光标前插入文本。

  • a:进入插入模式,在光标后插入文本。

  • Esc:退出插入模式,返回命令模式。

  • :w:保存文件。

  • :q:退出vi编辑器。

  • :wq:保存并退出。

  • dd:删除当前行。

  • yy:复制当前行。

  • p:粘贴文本。 有一个更现代化的neovim 在linux上使用sudo apt install neovim,然后在编辑文件的时候可以使用nvim,如果觉得麻烦,可以设置别名。如果是默认终端,就是有一个.bash_profile,或者bashrc文件。vim打开设置添加一行alias nvim='vim'

2. 冒号,q是退出,wq是保存退出(一定要记住的常用操作)

3. 如果上面两步不会,可以参照下图创建一个.c文件

4. 编译.c文件

方法一:我最常用

gcc -m32 -o test test.c

方法二:

gcc test.c -o test

gcc -Wall -g -o test test.c

-Wall 代表编译器在编译过程中会输出警告信息(Warning),比如有些变量你并没有使用,指针指向的类型有误,main 函数没有返回整数值等。这类信息虽然不是错误,不影响编译,但是很可能是程序 bug 的源头,也有助于你寻找代码中的错误,规范代码格式。所以建议每次编译时都加上 -Wall 参数。

-g 代表编译器会收集调试(debug)信息,这样如果你的程序运行出错,就可以通过 gdb 或者 lldb 等工具进行逐行调试,方便找出错误原因。如果你不是百分之百确定你的程序毫无问题,建议加上 -g 参数。这样 debug 的时候会方便很多。

-o 代表编译器会将编译完成后的可执行文件以你指定的名称输出到你指定的文件夹下。-o 的空格后的名称就是输出的文件的名称。例如我这里 -o 后是 test,就是说 gcc 会在编译成功后在我的当前目录下生成一个叫 test 的可执行文件。如果不加这个参数,每次编译后生成的可执行文件都会放在根目录下,名字叫做 a.out。每次编译成功后都会把上一次的 a.out 文件覆盖。所以建议加上 -o 参数,这样可以更加条理。

-m32:编译32位程序

5. 用gdb进行反汇编

disass main反汇编出来main函数的汇编代码

disass main反汇编出来test子函数的汇编代码

6. 设置断点

设置断点可以通过b或者break设置断点,断点的设置可以通过函数名、行号、文件名+函数名、文件名+行号以及偏移量、地址等进行设置。

break 函数名

break 行号

break 文件名:函数名

break 文件名:行号

break +偏移量

break -偏移量

break *地址

7. 运行

r是运行

n是单步执行,next遇到函数不会进入函数内部

si是步入,step会执行到函数内部

c是继续运行,调试时,使用continue命令继续执行程序。程序遇到断电后再次暂停执行;如果没有断点,就会一直执行到结束。

8. 删除断点

删除断点通过命令包括:

delete <断点id>:删除指定断点

delete:删除所有断点

clear

clear 函数名

clear 行号

clear 文件名:行号

clear 文件名:函数名

9. 查看断点

info br

简写:i b

练习:栈帧的形成与释放

#include <stdio.h>

int test(int a, int b) {
    int c = a + b;
    return c;
}

int main() {
    int d = test(1, 2);
}