20145329 《信息安全系统设计基础》第五周学习总结
教材学习内容总结
3.2程序编码
反汇编:把目标代码转为汇编代码的过程,把机器语言转换为汇编语言代码、低级转高级的意思
机器级编程的两种抽象:
机器级程序是围观我是和行为,定义为指令集体系结构,它定义了处理器状态、指令的格式,以及每条指令对状态的影响
机器级程序使用的存储地址是虚拟地址
查看目标代码文件的内容最有价值的是反汇编器,Linux中带-d命令行标志的程序OBJDUMP可以充当反汇编的角色:
unix> objdump -d 文件名
以“.”开头的行都是指导汇编器和链接器的命令
GCC可以产生sun函数的intel格式代码
unix> gcc -01 -S -masm=intel 文件名
3.3数据格式
所有指针都储存为4字节的双字
GCC用数据类型long double 来表示扩展精度的浮点值
3.4访问信息
一个IA32中央处理单元包含一组八个存储32位值得寄存器,最后两个寄存器(%ebp,%esp)保存着指向程序栈中重要位置的指针,根据管理的标准惯例才能修改他们的值
操作数三种类型:
立即数:任何能放进32位的字里的数值都可做立即数,表示:$+标准数
寄存器:表示寄存器的内容
存储器:根据计算的位置,访问某个存储器位置
MOV(传送)、MOVS(传送符号扩展的字节)、MOVZ(传送零扩展的字节),将一个较小原数据复制到一个较大数据位置,高位用符号扩展或零扩展填充
传送指令的两个操作数不能都指向存储器位置,将一个存储器复制到另一个存储器需要两条指令,要以寄存器为中介
IA32的栈向低地址方向增长,所以压栈是减小栈指针(寄存器%esp)的值,并将数据存放到存储器中,而出栈是从存储器中读,并增加栈指针的值,出栈的数据会保存在原存储器的位置,直到被覆盖。%esp指向的地址总是栈顶,程序可以用存储器寻址方法访问栈内任意位置
寄存器指针指向双字
寄存器访问比存储器访问要快得多
3.5算术与逻辑操作
leal指令没有其他大小的变种,主要用于进行地址计算
指令操作分类:
加载有效地址:leal指令,从存储器读到寄存器,实际没有引用寄存器,leal指令操作数必须是一个寄存器
一元操作:只有一个操作数,既是源又是目的,类似c语言中加一运算
二元操作:第二个操作数既是源又是目的,类似c语言的赋值运算,两操作数不能同时为存储器位置
移位:先给出移位量,移位量为立即数或放在寄存器元素%cl(特定寄存器)中,再给移位数值,移位量只能用单个字节编码,允许0到31位移位。
-
IA32两个“单操作数”乘法:
无符号数乘法:mull
有符号数乘法:imull
乘积放在寄存器%edx(高32位),%eax(低32位) -
除法:
有符号除法:idivl
设置被除数更常规的方法是cltd指令,将%eax扩展到%edx
无符号数采用的是divl指令,通常会事先将寄存器%edx设置为0
3.6控制
机器代码实现有条件行为的两种基本低级机制:测试数据值,然后根据测试的结果来改变控制流(更通用,更常见)或者数据流。jump指令可改变执行顺序。
- 条件码的三种使用方法:
1)根据条件码的某个组合,将一个字节置0或1
2)条件跳转到程序的某个其他部分
3)有条件的传送数据
CMP设置条件码而不更新目标寄存器,指令行为与SUB指令一样
TEST设置条件码而不改变目的寄存器的值,指令行为与AND指令一样
SET指令的操作数是一个字节的存储器位置,各SET指令的描述都适合的情况是:执行比较指令,根据计算t=a-b设置条件码
有符号比较测试基于SF^OF和ZF的组合,无符号数比较使用的是进位标志和零标志的组合
指令跳转通常用一个标号指明
-
无条件跳转jmp
直接跳转:目标作为指令的一部分(写法;直接给出标号)
间接跳转:跳转目标从寄存器或存储器位置中读出(写法:*后面跟操作数指示符) -
有条件跳转
条件跳转只能是直接跳转
跳转指令名字和跳转条件与SET指令时相匹配的
跳转指令编码方式:
(1)PC相关的跳转目标编码:目标指令地址与紧跟在跳转指令后面那条指令的地址之间的差作为编码,此种方式编码,寻址时程序计数器的值是跳转指令后面的那条指令的地址,而不是跳转指令本身的地址(只需两个字节)
(2)“绝对地址”编码:用四个字节直接指定目标
3.7过程
一个过程调用包括将数据和控制从代码的一部分传递到另一部分,需要在进入时为过程的局部变量分配空间,并在退出时释放这些空间。
数据传递、局部变量的分配和释放通过操纵程序栈来实现。
-
栈帧: 为单个过程分配的那部分栈
-
最顶端的栈帧以两个指针界定:
寄存器%ebp为帧指针
寄存器%esp为栈指针 -
程序执行时,栈指针可以移动,大多数信息的访问都是相对于帧指针的。
-
栈向低地址方向增长,栈指针%esp指向栈顶元素:
栈指针值适当减小可以分配没有指定初始值的数据的空间
类似的,可以通过增加栈指针来释放空间 -
call指令
目标:指明被调用过程起始的指令地址。
效果:将返回地址入栈,并跳转到被调用过程的起始处。 -
递归过程
当过程被调用时分配局部存储,返回时释放存储。
代码调试中的问题和解决过程
解决:由于git不熟练,把编好的代码复制到了一个单独的文件里,没有README.md这个文档,所以git失败,把要git的代码一次写到有README.md的这个文档里,git成功。
实践
本周代码托管截图
其他(感悟、思考等,可选)
感觉学起来还是挺难的,每次差不多周二就开始看书,但是还有其他课程要跟进,所以每次还是只能勉强看懂一部分,而且实践的内容总是练习的很慢,希望再学习两章能在看书时有更快更多的领悟。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 50/50 | 1/1 | 20/20 | |
第二周 | 50/100 | 1/2 | 30/50 | |
第三周 | 100/200 | 1/3 | 20/70 | |
第四周 | 0/200 | 0/3 | 20/90 | |
第五周 | 50/250 | 1/4 | 20/110 |