20145219 《信息安全系统设计基础》第05周学习总结

20145219 《信息安全系统设计基础》第05周学习总结

教材学习内容总结

实验楼实验练习

  • test.c实验代码

  • 命令编译成汇编代码test.s

  • 删除gcc产生代码中以"."开头的编译器指令,并保存为new.s

  • 为汇编代码注释栈帧情况

教材重点内容

  • X86 寻址方式:

      1 DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
      2 8086的分段模式
      3 IA32的带保护模式的平坦模式
    
  • ISA的定义

    指令集体系结构(ISA)定义了处理器状态、指令的格式、以及每条指令对状态的影响。大多数ISA包括IA32和x84-64,将程序的行为描述成好像每条指令是按顺序执行的。

  • 汇编命令与反汇编命令

    gcc -S xxx.c -o xxx.s 获得汇编代码,用gcc -c code.c产生目标文件code.o(二进制文件,无法直接查看),用objdump -d xxx.o反汇编可以查看目标代码文件内容。

    汇编代码(函数前两条和后两条汇编代码,所有函数都有,建立函数调用栈帧):

    前两条:

     pushl %ebp          将寄存器%ebp的内容压入程序栈
     movl %esp,%ebp      得到新栈低,将当前栈顶赋予栈低
    

    后两条:

     popl %ebp           过程调用结束,恢复旧栈低
     ret                 子程序的返回指令
    

    64位机器上想要得到32代码:gcc -m32 -S xxx.c

    gcc -S 产生的汇编中可以把 以”.“开始的语句都删除了再阅读。

  • 查看二进制文件

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

         od code.o | more
         od code.o > code.txt
    
  • 不同数据的汇编代码后缀

  • Linux和Windows的汇编格式区别

     1 Intel代码省略了指示大小的后缀。
     2 Intel代码省略了寄存器名字前面的'%'符号。
     3 Intel代码用不同的方式来描述寄存器中位置。
     4 在带有多个操作数的指令情况下,列出操作数的顺序相反。
    

    ATT是GCC、OBJDUMP和其它一些我们使用的工具的默认格式。Microsoft的工具、以及来自Intel的文档,其汇编代码都是Intel格式的。使用gcc -S -masm=intel code.c可以使GCC产生Intel格式的代码。

  • 寄存器

    esi edi可以用来操纵数组,esp ebp用来操纵栈帧。32位的eax,16位的ax,8位的ah,al都是独立的。

  • 寻址方式

  • 操作数三种类型

      立即数,即常数值
      寄存器,表示某个寄存器的内容
      存储器,根据计算出来的地址(有效地址)访问某个存储器位置。 
    
  • 有效地址

    计算方式 Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s

  • MOV

    MOV相当于C语言的赋值“=”,不能从内存地址直接MOV到另一个内存地址,要用寄存器中转一下。

    MOV类中的指令将源操作数的值复制到目的操作数中,源操作数指定的值是一个立即数,存储在寄存器或存储器中,目的操作数指定一个位置,要么是一个寄存器,要么是一个存储器地址。

  • push与pop

    先进后出:push将数据压入栈中,pop弹出,弹出的永远是最近被压入的。用数组实现栈,进行操作的一端为栈顶。栈向下增长,栈顶元素的地址是所有栈中元素地址中最低的。栈指针%esp保存栈顶元素的地址。

    源操作数、目的操作数应为字操作数。

  • 指针

    C语言中“指针”其实就是地址。

  • 局部变量

    局部变量通常是保存在寄存器中。因为,寄存器访问比存储器访问要快得多。

  • 算术和逻辑运算

1、一元操作:只有一个操作数,既是源又是目的,可以是一个寄存器,或者存储器位置。

2、二元操作:第一个操作数可以是立即数、寄存器或者存储器位置;第二个操作数既是源也是又是目的,可以是寄存器或者存储器位置,但是不能同时是存储器位置。

操作的顺序:第二个操作数 操作符 第一个操作数

3、移位操作:先给出移位量,第二项给出要移位的数值。

源操作数(移位量):立即数或者放在单字节寄存器元素%cl中。目的操作数:一个寄存器或是一个存储器位置。
  • 控制

    有条件跳转的条件看状态寄存器(教材上叫条件码寄存器) 注意leal不改变条件码寄存器。

    1、分支(if/switch)

    C语言if-else 语句:

      if(test-expr)
          then-statement
      else
          else-statement
    
      (注:test-expr    整数表达式[假/真])
    

    汇编实现形式:

      t = test-expr;
      if (!t)
          goto false;
      then-statement
      goto done;
      false: 
          else-statement
      done:
    

    2、循环(while, for)

    C语言do-while循环:

      do
          body-statement
          while(test-expr);
    

    汇编实现形式:

      loop:
          body-statement
          t = test-expr;
          if(t)
              goto loop;
    

    while循环、for循环均需转换成do-while形式在转换

    3、switch语句

    执行switch语句的关键步骤是通过跳转表来访问代码位置。

  • IA32

    IA32利用程序栈来支持过程调用(包括将数据和控制)。为单个过程分配的那部分栈做栈帧。最底端(地址最大)%ebp为帧指针;最顶端(地址最小)%esp为栈指针。当程序执行时,栈指针可以移动。

  • 转移

    1、call指令

      目标:指明被调用过程起始的指令地址。
      效果:将返回地址入栈,并跳转到被调用过程的起始处。
    

    2、ret指令

      从栈中弹出地址,并跳转到这个位置.
      使用这个指令时,栈指针要指向前面call指令存储返回地址的位置。
    

gdb代码调试过程

课后作业中的问题和解决过程

  • 问题:p148 3.29通过阅读汇编代码和跳转表补填C语言代码中的缺失部分,我不明白课后答案中case 几 是怎么得出的,越读越混乱,截至上交博客时还未解决。

本周代码托管截图

  • 代码托管连接
  • 老师上周让我改托管代码的格式,不要都混在一起,我这周尝试多次都不成功,还把原来已经托管的代码弄的一团乱,没有办法了,我只好重新新建了一个项目重新上传之前的和这次的代码,以前的那个项目太乱了已经删除了。

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

本周的知识是与汇编语言相关的,在上学期的汇编语言学习过程中,我已经了解并基本掌握了一些寻址方式和汇编语言指令,能够阅读简单的汇编语言代码。本周的学习,我把重点放在C语言代码的汇编和反汇编、C语言代码和汇编代码的转换以及加强阅读汇编代码的能力提高上。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第零周 0/0 1/1 15/15
第一周 0/0 1/2 25/40
第二周 62/62 1/3 25/65
第三周 176/238 1/4 20/85
第五周 57/295 1/5 20/105

参考资料

posted @ 2016-10-16 17:40  20145219宋歌  阅读(201)  评论(4编辑  收藏  举报