2017-2018-1 20155207 《信息安全系统设计基础》第5周学习总结
教材学习内容总结
这章为咱们讲述了如何有C编译器生成的x86-84机器代码,还讲述了过程的实现,包括栈分配、寄存器使用惯例和参数传递。html
第三章 程序的机器级表示
- 计算机执行机器代码,用字节序列编码低级的操做
- GCC C以汇编代码的形式产生输出,汇编代码是机器代码的文本表示
- 3.1 历史观点
- 平坦寻址模式:程序员将整个存储空间看做一个大的字节数组,Linux和DOS使用
- 分段模式:8086
- IA32:带保护模式的平坦寻址方式
- 3.2 程序编码
- 编译P1.c和P2.c:gcc -01 -o -m32 p p1.c p2.c
-01
第一级优化,编译时间长,程序性能方面考虑,第二级优化是较好的选择
- C预处理器扩展源代码,汇编器产生源代码的汇编代码后缀
.s
,汇编器再将汇编代码转换成二进制目标代码后缀.o
, 连接器将目标代码文件与实现库函数的代码合并,产生最中国的可执行代码文件p
- 3.2.1 机器级代码
- 指令集体系结构(ISA):机器级程序的格式和行为,定义了处理器状态、指令的格式以及每条指令对状态的影响
- 虚拟地址:使用的存储器地址
- 程序计数器(PC):指示下一条指令在存储器中的地址
- 寄存器文件:8个命名的位置,分别存储32位的值,能够存储地址或整数数据
- 条件码寄存器:实现控制或数据流中的条件变化
- 浮点寄存器
- 3.2.2 代码示例
- 命令行中使用
-s
获得汇编代码,使用-c
会编译并汇编
- 反汇编器:带
-d
命令行标志的程序OBJDUMP
- 3.2.3 关于格式的注解
- 3.3 数据格式
- 字表示16位数据类型
- int、long int、全部指针都用双字,浮点数单精度4字节、双精度8字节、扩展精度10字节
- 3.4 访问信息
- 3.4.1 操做数指示符
- 操做数三种类型:当即数(
$-577
)、寄存器(Ea
表示寄存器R[Ea]
表示寄存器值)、存储器(Mb[Addr]
表示对存储在存储器中从地址Addr开始的b个字节值的引用)
- 3.4.2 数据传送指令
- MOV传送,MOVS符号拓展,MOVZ零拓展
- 将一个值从一个存储器位置复制到另外一个存储器位置须要两条指令
- 3.4.3 数据传送实例
- 3.5 算数和逻辑操做
- 3.5.1 加载有效地址
leal
将源操做数存储器的地址写入到目的操做数寄存器中
- 3.5.2 一元操做和二元操做
- 一元操做操做数能够是寄存器或存储器位置
- 二元操做第一个操做数能够是当即数、寄存器或存储器位置,第二个操做数能够是寄存器或存储器位置,两操做数不能同时为存储器位置
- 3.5.3 移位操做
- SAL、SRL都是左移指令,SAR算数右移、SLR逻辑右移
- 3.5.4 讨论
- 编译器产生的代码中,会用一个寄存器存放多个程序值,还会在寄存器之间传送程序值
- 3.5.5 特殊的算数操做
- 无符号乘法(mull)补码乘法(imull):一个参数必须存放在%eax,而另外一个做为指令的源了操做数给出,乘积存放在%edx和%eax中
- 除法将%edx和%eax中的64位数做为被除数,商存储在%eax中,余数存储在%edx
- 3.6 控制
- 3.6.1 条件码
- CF进位标志,检查无符号数的溢出
- ZF零标志
- SF符号标志
- OF溢出标志
- 除了只设置条件码而不更新目标寄存器外,CMP与SUB行为相同,TEST与ADD行为相同
- 3.6.2 访问条件码
- 条件码使用方法:1)根据条件码的组合,设置字节为0或1 2)条件跳转到程序其余部分 3)条件传送数据
- SET指令的目的操做数是8个单字节寄存器元素之一或是存储一个字节的存储器位置
- 3.6.3 跳转指令及其编码
- 直接跳转:跳转目标是做为指令的一部分编码的
- 间接跳转:跳转目标是从寄存器或存储器位置中读出的
- 执行与PC相关寻址时,程序计数器的值是跳转指令后面的那条指令的地址
- 3.6.4 翻译条件分支
- 3.6.5 循环
- do-while循环:至少执行一次
- while循环:第一次执行以前,循环可能停止,使用条件分支,在须要时省略循环体的第一次执行
- for循环:先给出初始化条件
- 3.6.6 条件传送指令
- 基于条件数据传送的代码比基于条件控制转移的代码性能好
- 3.6.7 switch语句
- 使用跳转表
- 跳转表对重复状况的处理是使用相同的代码标号,对缺失状况的处理使用默认标号
- 3.7 过程
- 数据传递、局部变量的分配和释放经过操纵程序栈来实现
- 3.7.1 栈帧结构
- IA32用程序栈支持过程调用
- 机器用栈来传递过程参数、存储返回信息、保存寄存器用于之后恢复
- 栈帧:为单个过程分配的栈
- %ebp为帧指针、%esp为栈指针,栈指针能够移动,大多数信息访问相对于帧指针
- 3.7.2 转移控制
- call指令的效果:返回地址入栈,并跳转到被调用过程的起始处,返回地址是在程序中紧跟在call后面那条指令的地址
- ret指令从栈中弹出地址
- 3.7.3 寄存器使用惯例
- 程序寄存器组是惟一能被全部过程共享的资源
- %eax、%edx、%ecx被划分为调用者保存寄存器
- %ebx、%esi、%edi被划分为被调用者保存寄存器
- 3.7.4 过程示例
- “创建”初始化栈、“主体”执行过程实际计算、“结束”恢复栈初始状态以及过程返回
- 3.7.5 递归过程
教材学习中的问题和解决过程
- 练习3.33 D
- 作此题的时候,很不理解%esp和偏移量为+四、+8两个位置存储的数值是如何造成的,后来反复研究GCC生成的汇编代码,发现是将字符串“%x %x”存储在%esp的位置,同时经过leal命令,将x和y的位置存储在+八、+4的位置
代码调试中的问题和解决过程
(statistics.sh脚本的运行结果截图)java
上周考试错题总结
- 把add.c sub.c mul.c div.c编译成一个共享库libmath.so的命令是:gcc -shared -fpic -o libmath.so add.c sub.c mul.c div.c
- Linux中,目标文件XXX.o中的代码和数据节是从地址0开始的
结对及互评
点评模板:
- 博客中值得学习的或问题:
- 代码中值得学习的或问题:
- 其余
本周结对学习状况
- [20155223](http://www.cnblogs.com/battlefieldheros/p/7705963.html)
- 结对照片
- 结对学习内容
- XXXX
- XXXX
- ...
其余(感悟、思考等,可选)
这周学习了将C语言代码转化为汇编代码,上学习有学过汇编这门课,因此前面一些代码仍是有些熟悉的,对于后面不大熟悉的汇编代码,能够经过学习这张来温习git
学习进度条
目标 |
5000行 |
30篇 |
400小时 |
|
第一周 |
200/200 |
2/2 |
20/20 |
|
第二周 |
300/500 |
2/4 |
18/38 |
|
第三周 |
500/1000 |
3/7 |
22/60 |
|
第四周 |
300/1300 |
2/9 |
30/90 |
|
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进本身的计划能力。这个工做学习中很重要,也颇有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。程序员
参考:软件工程软件的估计为何这么难,软件工程 估计方法数组
计划学习时间:8小时安全
实际学习时间:8小时函数
改进状况:性能
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)学习
参考资料