20145308 《信息安全系统设计基础》第2周学习总结
教材学习内容总结
实验楼学习
- 实验二 GCC的使用
- 编译器GCC的使用
- gcc 支持编译的一些源文件后缀名
.c
C语言源文件
.C
.cc
.cxx
C++源文件
.m
Object-C源文件
.i
经过预处理后的C源文件
.ii
经过预处理后的C++源文件
.s
.S
汇编语言源文件
.h
预处理文件(头文件)
.o
目标文件
.a
存档文件 - gcc 编译程序的流程:
.c
-->.i
-->.s
-->.o
- 预处理:gcc –E hello.c –o hello.i;gcc –E调用cpp
编 译:gcc –S hello.i –o hello.s;gcc –S调用ccl
汇 编:gcc –c hello.s –o hello.o;gcc -c 调用as
链 接:gcc hello.o –o hello ;gcc -o 调用ld - 用 gcc 编译一个经典 C 程序
- gcc 到底背着我们做了什么:调用预处理程序,由它负责展开在源程序中定义的宏
gcc -E hello.c -o hello.i
将hello.i编译为目标代码gcc -c hello.i -o hello.o
gcc连接器将目标文件链接为一个可执行文件,一个大致的编译流程结束gcc hello.o -o hello
- gcc 支持编译的一些源文件后缀名
- gcc 编译模块化的程序
- 编译器GCC的使用
- 实验三 GDB使用
- GDB概述
- 使用gdb调试:
gcc –g gdb.c -o testgdb
启动GDBgdb testgdb
设置断点b XX
运行r
下一步n``s
跳过循环,不用单步执行until
设置临时断点tb
打印函数调用堆栈bt
查看变量值p
从当前断点继续运行到下一个断点c
条件断点b 12 if i=1500
每次执行展示display j
退出函数finish
退出GDBq
- 使用GDB:编译时加入参数
-g
gdb <program> programe
- 使用gdb调试:
- GDB概述
- 实验四 Makefile使用
- Makefile基本写法:test(目标文件): prog.o code.o(依赖文件列表)
tab(至少一个tab的位置) gcc prog.o code.o -o test(命令)
....... - 使用宏的Makefile:定义宏
宏名=原变量
,使用宏的格式(宏名)
- Makefile基本写法:test(目标文件): prog.o code.o(依赖文件列表)
第一章 计算机系统漫游
- 1.1 信息就是位+上下文
- 文本文件:由ASCII字符构成的文件 二进制文件:其他文件
- 在不同的上下文中,一个同样的字节序列可能表示不同信息
- 1.2 程序被其他程序翻译成不同的格式
- 从源文件到目标文件的转化是由编译器驱动程序完成
gcc -o hello hello.c
- 编译系统:预处理器、编译器、汇编器和链接器
- 预处理阶段:
.c
->.i
,根据以字符#
开头的命令,修改原始的C程序 - 编译阶段:
.i
->.s
,汇编语言程序 - 汇编阶段:
.s
->机器语言指令,打包成可重定位目标程序 - 链接阶段:
可重定位目标程序
->可执行目标程序
- 预处理阶段:
- 从源文件到目标文件的转化是由编译器驱动程序完成
- 1.3 了解编译系统如何工作是大有益处的
- 知道编译系统是如何工作的:优化程序性能、理解链接时出现的错误、避免安全漏洞
- 1.4 处理器读并解释存储在存储器中的指令
shell
命令行解释器,输入的命令行第一个单词不是内置的外壳命令,那么外壳就会假设这是一个可执行文件的名字- 1.4.1 系统的硬件组成
- 总线:贯穿整个系统的一组电子管道,携带信息字节并负责在各个部件间传递
- I/O设备: 系统与外界的联系通道,通过一个控制器或适配器与I/O总线相连
- 主存:临时存储设备,处理器执行程序时,用来存放程序和程序处理的数据,由一组动态随机存取存储器(DRAM)芯片组成
- 处理器:中央处理单元(CPU),解释(或执行)存储在主存中的指令的引擎
- 1.4.2 运行hello程序
- 1.5 高速缓存至关重要
- 高速缓存存储器:静态随机访问存储器(SRAM)实现
- 1.6 存储设备形成层次结构
- 每个计算机系统中的存储设备都被组织成了一个存储器层次结构
- 一层上的存储器作为低一层存储器的高速缓存
- 1.7 操作系统管理硬件
- 操作系统两个基本功能:1)防止硬件被失控的应用程序滥用 2)向应用程序提供简单一致的机制来控制复杂而大相径庭的低级硬件设备
- 操作系统通过几个基本的抽象概念(进程、虚拟存储器和文件)来实现这两个功能
- 1.7.1 进程
- 对处理器、主存和I/O设备的抽象表示
- 进程是操作系统对一个正在运行的程序的的一种抽象
- 并发运行:一个进程的指令和另一个进程的指令是交错进行的
- 上下文切换:操作系统实行交错执行的机制
- 1.7.2 线程
- 一个进程实际上可以由多个称为线程的执行单元组成,每个线程都运行在进程的上下文中,并共享同样的代码和全局数据
- 1.7.3 虚拟存储器
- 虚拟存储器是一个抽象概念,为每个进程提供了一个假象,即每个进程都在独占地使用主存
- 每个进程看到的是一致的存储器,称为虚拟地址空间
- 程序代码和数据:代码和数据区是直接按照可执行目标文件的内容初始化的
- 堆:堆可以在运行时动态地扩展和收缩
- 共享库:存放共享库的代码和数据的区域
- 栈:位于用户虚拟地址空间顶部的是用户栈,编译器用他实现函数调用,用户栈在程序执行期间可以动态地扩展和收缩
- 内核虚拟存储器:内核总是驻留在内存中,是操作系统的一部分,地址空间顶部区域为内核保留
- 1.7.4 文件
- 文件是字节序列,I/O设备的虚拟表示
- 系统中的所有输入输出都是通过使用一小组称为Unix I/O的系统函数调用读写文件来实现的
- 1.8 系统之间利用网络通信
- 1.9 重要主题
- 1.9.1 并发和并行
- 并发:一个同时具有多个活动的系统
- 并行:用并发使一个系统运行得更快
- 线程级并发:多处理器系统(由单操作系统内核控制的多处理器系统)要求程序是以多线程的方式来书写的,这些线程也可以并行的高效执行
- 指令级并行:现代处理器可以同时执行多条指令的属性 超标量处理器:处理器可以达到比一个周期一条指令更快的执行速率
- 单指令、多数据并行:允许一条指令产生多个可以并行执行的操作
- 1.9.2 计算机系统中抽象的重要性
- 1.9.1 并发和并行
第七章 链接
- 链接:将各种代码和数据部分收集起来并组合成为一个单一文件的过程,文件可以被加载到存储器并执行
- 7.1 编译器驱动程序
- 7.2 静态链接
- 链接器两个主要任务:符号解析、重定位
- 7.3 目标文件
- 可重定位目标文件:包含二进制代码和数据
- 可执行目标文件:可直接被拷贝到存储器并执行
- 共享目标文件:特殊类型的可重定位目标文件,可以在加载或者运行时被动态地加载到存储器并链接
- 目标文件格式:
a.out
COFF
(一般目标文件格式)PE
(可移植可执行)ELF
(可执行可链接)
- 7.4 可重定位目标文件
- 7.5 符号和符号表
- 全局符号
- 外部符号
- 本地符号
- 7.6 符号解析
- 7.6.1 链接器如何解析多重定义的全局符号
- 强符号:函数和已初始化的全局变量
- 弱符号:未初始化的全局变量
- 处理多重定义符号规则:1.不允许有多个强符号 2.一个强符号和多个弱符号,选择强符号 3.多个弱符号,从弱符号中任意选择一个
- 7.6.2 与静态库链接
- 静态库:编译系统将所有相关目标文件打包成一个单独文件,可用作链接器的输入
- 静态库以一种称为存档的特殊文件格式存放在磁盘中,存档文件名由后缀
.a
标识 - 创建静态库:使用AR工具
gcc -c XX.c
ar rcs libXX.a(静态库名) XX.o(添加的程序)
- 使用静态库:编译连接输入文件和静态库
gcc -O2 -c XX.c(调用静态库程序名)
gcc -static -o p2 XX.o(调用静态库程序名) libXX.a(静态库)
- 7.6.3 链接器如何使用静态库来解析引用
- 7.6.1 链接器如何解析多重定义的全局符号
- 7.7 重定义
- 合并输入模块并为每个符号分配运行时的地址
- 重定义时两步:重定位节和符号定义 重定位节中的符号引用
- 7.7.1 重定位条目
- 汇编器遇到对最终位置未知的目标引用
- 7.7.2 重定位符号引用
- 重定位符号引用
- 重定位绝对引用
- 7.8 可执行目标文件
- 7.9 加载可执行目标文件
- 7.10 动态链接共享库
- 共享库(共享目标):目标模块,在运行时,可以加载到任意的存储地址,过程称为动态链接,由动态链接程序执行
- 共享库的生成
gcc -fPIC -c xxx.c
gcc -shared -o libxxx.so xxx.o
共享库的使用:gcc -o main main.c -L. -lxxx
- 7.11 从应用程序中加载和链接共享库
- 分发软件
- 构建高性能的Web服务器
- 7.12 与位置无关的代码(PIC)
- 编译库代码:与位置无关的代码,使用
-fPIC
选项指示GNU编译系统生成PIC代码 - PIC数据引用
- 全局偏移量表
- PIC函数调用
- 编译库代码:与位置无关的代码,使用
- 7.13 处理目标文件的工具
- AR:创建静态库,插入、删除、列出和提取成员
- STRINGS:列出一个目标文件中所有可打印的字符串
- STRIP:从目标文件中删除符号表信息
- NM:列出一个目标文件的符号表中定义符号
- SIZE:列出目标文件中节的名字和大小
- READELF:显示一个目标文件的完整结构,包含SIZE和NM的功能
- OBJDUMP:所有二进制工具之母,显示一个目标文件的所有信息,反汇编
- LDD:列出一个可执行文件在运行时所需要的共享库
代码调试中的问题和解决过程
-
问题:程序编译成功,但是不输出结果
-
解决:没有输入执行命令,
./main
课后作业中的问题和解决过程
- Git代码出现问题
- 还没有解决,需要再研究,本周提交代码还采用的是粘贴的方式,自己研究后出现了新的问题
本周代码托管截图
其他(感悟、思考等,可选)
- 本周主要学习了Linux下的开发环境,主要学习内容有三个vim、gcc、gcd,本周主要学习了命令行和程序编译的过程,参数很多,但是用了娄老师提供的方法记忆就好很多,代码提交的方法还不是很会,需要再研究
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 1/2 | 25/30 | 学习Linux指令 | |
第二周 | 50/50 | 1/3 | 25/55 | Linux系统下的开发环境 |