计算机系统基础——c语言拾遗(机制)1

172 阅读3分钟

计算机系统基础

前言


一、C语言拾遗:机制?

在IDE里,为什么按一个键,就能编译运行?

  • 编译、链接 .c ->预编译(gcc -E)->.i>编译(gcc -S) ->.s->汇编 (gcc -c)->.o->链接->a.out

  • 加载运行 ./a.out

背后是通过调用命令行工具完成的

  • RTFM:gcc --help;man gcc
  • 控制行为的三个选项:-E,-S,-c

本次课程

  • 预热:编译、链接、加载到底做了什么?
  • RTFSC时需要关注的c语言特性

输入命令:

命令作用
cd /Desktop转到桌面目录
mkdir ics2020新建一个文件夹ics2020
cd ics2020进入ics2020目录
touch a.c新建一个a.c文件
vim a.c 编辑a.c(1)按键i 进入编辑模式 输入 int main(){}(2)按esc 然后输入:wq保存退出
gcc a.c编译a.c文件生成可执行文件a.out
./a.out执行可执行文件
echo $?查看上次函数执行的返回结果
vim a.out编辑可执行文件,可以查看出ELF说明是可执行文件

在其中点击esc键,然后输入:%!xxd可以将01转为16进制的文件

image.png

命令作用
file a.out查看文件的详细信息
gcc --help可以查看gcc的文档
tldr gcc可以查看gcc的简易命令
objdump -d 二进制文件反汇编

image.png

image.png

image.png

ELF代表可执行文件

进入C语言之前:预编译

image.png

#include 文件:就是将文件原样复制到这个位置

image.png

通过gcc a.out --verbose 打印出编译连接时的详细信息

下述显示出了gcc可以编译成很多版本的二进制文件,以及当前gcc的版本 image.png

image.png

如果将“” 写成<>则其默认会去指定目录下寻找该文件,找不到就报错

image.png 所以将其通过 -I.的命令,将当前目录添加到<>指定目录列表下,那么就能编译成功

image.png

输入命令:gcc a.c -I. --verbose 可以发现

image.png

.被加入到了<>的查看目录下面

有趣的预编译

image.png

输出yes 因为在当前环境里面宏定义aa和bb都没有被定义,所以等号成立(在预编译里面,可以出现未被定义的宏,因为本质是字符串替换,如果没有宏可以替换,那么就是未被定义)

image.png

如下输出的就是no

宏定义与展开

image.png

注意在c语言中,宏定义两个字符会自动进行拼接:比如 image.png

“##”在宏定义里面用于连接两个字符 比如sys ## tem 就是system

__like__ ”代表当前的行号 重定义true

#define SYSTEM sys ## tem

#define true (__like %2 !=0

image.png

image.png

可以简化程序书写

下面的程序就是打印出hello Tome hello Jerry。。。 image.png

image.png

编译、汇编、链接

image.png

编译 (将c语言转为汇编)

image.png

image.png

汇编(将汇编转为二进制)

image.png

链接(将两个文件链接到一起)

image.png

image.png

C语言执行的两个视角

image.png 内存可以看成一块连续的数组

c语言的一切都是指针

image.png

void * p:代表地址 int *p:除了代表地址,还说明了指针指向读取的类型

image.png 不论是int * 还是****,不论有多少个*,都是地址

image.png

image.png

编程理解指针的实际用法

总结

上面将来程序里的一些过程,预处理,编译,汇编,链接,执行