20155236 2017-2018-1 《信息安全系统设计基础》第5周学习总结

20155236 2017-2018-1 《信息安全系统设计基础》第5周学习总结

教材学习内容总结

程序的机器级表示

程序编码

  • GCC将源代码转化为可执行代码的步骤:
    C预处理器——扩展源代码-生成.i文件
    编译器——产生两个源代码的汇编代码-——生成.s文件
    汇编器——将汇编代码转化成二进制目标代码——生成.o文件
    链接器——产生可执行代码文件

  • 机器级代码:
    机器级程序使用的存储器地址是虚拟地址
    看上去是一个非常大的字节数组,实际上是将多个硬件存储器和操作系统软件组合起来

二进制文件可以用od命令查看,也可以用gdb的x命令查看。有些输出内容过多,可以使用more或less命令结合管道查看,也可以使用输出重定向来查看。
od code.o | more
od code.o > code.txt

数据格式

C声明 汇编代码后缀 大小(字节)
char b- 字节 1
short w- 字 2
int l- 双字 4
long l- 双字 4
long long int - 8
char * l- 双字 4
float s- 单精度 4
double l- 双精度 8
long double t- 扩展精度 10/12
  • 多数GCC生成的汇编代码指令都有一个字符后缀,表明操作数的大小。

访问信息

  • 一个IA32的中央处理器单元包含一组8个存储32位数值的寄存器。所有八个寄存器都可以作为16位(字)或32位(双字)来访问:
    1.%esi,%edi可以用来操纵数组
    2.%esp,%ebp用来操纵栈帧
    3.64位的%rax,32位的%eax,16位的%ax,8位的%ah,%al都是独立的
  • 有效地址的计算方式:Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s

控制

  • 设置条件码:只设置条件码而不改变任何其他寄存器
    1.CMP指令根据它们的两个操作数之差来设置条件码
    2.TEST指令的行为与AND指令一样,除了它们只设置条件码而不改变目的寄存器的值。典型的用法是,两个操作数是一样的,或其中的一个操作数是一个掩码,用来指示哪些位应该被测试。

  • 跳转指令及其编码:JUMP指令
    1.直接跳转:后面跟标号作为跳转目标
    2.间接跳转:*后面跟一个操作数指示符
    当执行与PC相关的寻址时,程序计数器的值是跳转指令后面的那条指令的地址,而不是跳转指令本身的地址。

过程

IA32程序用程序栈来支持过程调用。它包括将数据(参数和返回值)和控制从代码的一部分传到另一部分,另外还包括进入时为过程的局部变量分配空间,并在退出时释放空间。一般地,机器只提供转移控制到过程和从过程中转移出控制的简单指令,数据传递、局部变量的分配和释放必然通过程序栈实现。
机器用栈来传递过程参数、存储返回信息、保存寄存器用于以后恢复,以及本地存储。为单个过程分配的那部分栈称为栈帧。最顶端的栈帧以两个指针界定,寄存器%ebp为帧指针,寄存器%esp为栈指针。
栈指针%esp可以移动,帧指针%esp不变化,因而大多数信息的访问都是相对于帧指针的。如下图所示:
图1

  • leave指令:返回准备栈,等价于:
movl %ebp,%esp
popl %ebp //恢复已保存的%ebp寄存器
  • ret指令:从过程调用中返回。从栈中弹出地址,并跳转到这个位置

函数调用栈信息的GDB命令

  • backtrace/bt n
    n是一个正整数,表示只打印栈顶上n层的栈信息。
    n表一个负整数,表示只打印栈底下n层的栈信息。
  • frame n
    n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。
    这个指令的意思是移动到n指定的栈帧中去,并打印选中的栈的信息。如果没有n,则打印当前帧的信息。
  • up n
    表示向栈的上面移动n层,可以不打n,表示向上移动一层。
  • down n
    表示向栈的下面移动n层,可以不打n,表示向下移动一层。

教材学习中的问题和解决过程

  • 寄存器使用惯例

  • 调用者调用被调用者时,要求被调用者不能覆盖某个调用者稍后会使用的寄存器值。根据惯例,寄存器%eax、%edx、%ecx称为调用者保存寄存器。P调用Q时,Q可以覆盖这些寄存器而不会破坏任何P需要的数据(因为会恢复)。另一方面,寄存器%ebx、%esi等被划分为被调用者保存寄存器。要求Q必须在覆盖这些寄存器值之前,先把它们保存到栈中,并在返回前恢复它们。

  • 保存某值的两种方式:由调用者保存,在调用之前就压进栈;由被调用者保存,在刚被调用的时候就压进栈,并在返回之前恢复。

代码调试中的问题和解决过程

其他(感悟、思考等,可选)

这周是在我们所学的8086汇编知识的基础上,对上学期汇编 知识的一个巩固。
但本次学习的主要用于32位机器,引入了新的寄存器,操作指令更改为向右赋值。但宗其本质,一条机器指令只执行一个非常基本的操作以及汇编语言是近似机器语言,其造作指令与机器码一一对应。

本周结对学习情况

  • 一个IA32的中央处理器单元包含一组8个存储32位数值的寄存器。所有八个寄存器都可以作为16位(字)或32位(双字)来访问:
    %esi,%edi可以用来操纵数组
    %esp,%ebp用来操纵栈帧
    64位的%rax,32位的%eax,16位的%ax,8位的%ah,%al都是独立的

代码截图

图4

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 10/10 1/1 10/10
第二周 100/100 1/2 19/25
第三周 200/278 1/3 10/36
第四周 290/568 1/4 10/46
第五周 310/878 1/5 10/56
posted @ 2017-10-22 13:15  Heineken  阅读(169)  评论(0编辑  收藏  举报