2017-2018-1 20155212 《信息安全系统设计基础》第13周学习总结
教材学习内容总结
历史观点
- X86 寻址方式经历三代
- DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
- 8086的分段模式
- IA32的带保护模式的平坦模式
- 摩尔定律:预测在未来十年,芯片上的晶体管数量每年都会翻一番。
程序编码
- 编译选项
-Og
告诉编译器使用会生成符合原始C代码整体结构的机器代码的优化等级,使用较高级别游湖产生的代码会严重变形。 - 重要的两种抽象
- 由指令集体系结构或指令集架构来定义机器级程序的格式和行为
- 机器级
- %rip给出下一条指令在内存中的地址
objdump -d *.o
反汇编- Ubuntu中
gcc -S *.c
更接近教材中代码(删除.开头语句) - 注意
- x86-64指令长度从1-15个字节不等
- 反汇编器使用的指令命名规则与GCC生成的汇编代码用的有些细微的差别
- 用汇编代码来访问机器的低级特性
- 用汇编代码编写整个函数,在链接阶段把它们和 C函数组合起来
- 利用GCC的支持,直接在C程序中嵌入汇编代码
- 二进制文件可以用od命令查看,也可以用gdb的x命令查看。有些输出内容过多,我们可以使用more或less命令结合管道查看,也可以使用输出重定向来查看
- ATT与Intel汇编代码格式
数据格式
- C语言数据类型在X86-64中的大小。在64位机器中,指针长8字节。
C声明 | Intel数据类型 | 汇编代码后缀 | 大小(字节) |
---|---|---|---|
char | 字节 | b | 1 |
short | 字 | w | 2 |
int | 双字 | l | 4 |
long | 四字 | q | 8 |
char* | 四字 | q | 8 |
float | 单精度 | s | 4 |
double | 双精度 | l | 8 |
访问信息
- 整数寄存器
- esi edi可以用来操纵数组
- esp ebp用来操纵栈帧
- 32位的eax,16位的ax,8位的ah,al都是独立的
操作数格式(s=1, 2, 4, 8)
格式 | 操作数值 |
---|---|
Imm(rb, ri, s) | M[Imm+R[rb]+R[ri]·s] |
- MOV相当于赋值
- 不能从内存直接MOV到另一个内存,要用寄存器中转
- MOV指令示例(源操作数,目的操作数)
- MOV指令大小匹配,MOVZ和MOVS将较小的源值复制到较大的目的
- MOVZ类将目的中剩余的字节填充为0
- MOVS类通过符号扩展来填充,把源操作数的最高位进行赋值
- MOVZ类将目的中剩余的字节填充为0
- 局部变量通常是保存在寄存器中,而不是内存中。访问寄存器比访问内存要快得多。
- 当执行强制类型转换既涉及大小又涉及C语言中符号变化时应该先改变大小。
- 栈
- 压栈:减小栈指针的值,再存放数据
- 弹栈:从内存中读数据,并增加栈指针的值
- 栈“顶”在底部
算术和逻辑操作
- 加载有效地址指令
leaq
实际上是movq
指令的变形。将有效地址写入到目的操作数,目的操作数必须是一个寄存器。 - 加1、减1、取负、取补操作:一元操作,操作数是寄存器或内存位置
- 加、减、乘、除、异或、或、与:二元操作,第一个操作数可以是立即数、寄存器或是内存位置,第二个操作数可以是寄存器或是内存位置
- 移位操作:移位量可以是一个立即数,或者放在单字节寄存器%cl中
- 减法:第二操作数-第一操作数
控制
- 条件码
- CF:进位
- ZF:零
- SF:符号
- OF:溢出
- 跳转指令
- 无条件跳转
- 直接跳转给出一个标号作为跳转目标。
jmp .L
- 简介跳转:‘*’后面跟一个操作数指示符
- 用寄存器中的值作为跳转目标:
jmp *%r
- 用进村其中的值作为读地址:
jmp *(%r)
- 用寄存器中的值作为跳转目标:
- 直接跳转给出一个标号作为跳转目标。
- 有条件跳转(只能是直接跳转)
- 指令的名字和跳转条件与SET指令的名字和设置条件是相匹配的
- 无条件跳转
if-else
t=test-expr; if(!t) goto false; then statement goto done; false: else-statement done:
do-while循环
loop: body-statement t = test-sxpr; if(t) goto loop;
- while循环
- 跳转到中间
goto test; loop: body-statement test: t=test-expr; if(t) goto loop;
- guarded-do
loop: body-statement t = test-sxpr; if(t) goto loop;
for循环
intit-expr; while(test-expr) { body-statement update-expr; }
while循环的翻译方式根据优化等级决定。
过程
教材学习中的问题和解决过程
- 【问题一】如何将汇编代码编写的函数与C函数组合?
- 【问题二】如何在C程序中嵌入汇编代码?
- 【问题三】leaq作为加载有效地址指令,实际上是movq的变形。那么leaq与movq的用法有什么不同?
- 【问题三】CMP和SUB用在什么地方?
- CMP应该是用在对操作数进行测试的时候,比如,可以测试某个数与已知数的大小关系等;而SUB执行的是减法操作,用于普通运算中
- 【问题四】while循环有两种翻译方式,这两种翻译方式分别什么时候使用呢?
- 较低优化等级编译时(-Og)会采用跳转到中间的策略,较高优化等级时采用guarded-do策略
代码调试中的问题和解决过程
- 问题1:XXXXXX
- 问题1解决方案:XXXXXX
- 问题2:XXXXXX
- 问题2解决方案:XXXXXX
- ...
代码托管
(statistics.sh脚本的运行结果截图)
上周考试错题总结
- 错题1及原因,理解情况
- 错题2及原因,理解情况
- ...
课后重点习题
3.1
3.3
3.5
3.6
3.9
3.14
3.15
3.16
3.22
3.23
3.27
3.29
3.30
3.33
3.34
其他(感悟、思考等,可选)
xxx
xxx
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 96/96 | 1/1 | 15/15 | |
第二周 | 30/126 | 1/2 | 21/36 | |
第三周 | 30/156 | 1/3 | 21/57 | |
第四周 | 10/156 | 1/4 | 20/77 | |
第五周 | 23/189 | 3/7 | 20/97 | |
第六周 | 201/390 | 3/10 | 18/115 | |
第七周 | 0/390 | 2/12 | 20/135 | |
第八周 | 0/390 | 3/15 | 22/157 | |
第九周 | 284/674 | 3/18 | 25/182 | |
第十周 | 53/727 | 1/19 | 15/197 | |
第十一周 | 612/1339 | 2/21 | 26/223 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
计划学习时间:XX小时
实际学习时间:XX小时
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)