信息安全系统设计基础第五周学习总结

                                                              信息安全系统设计基础第五周学习总结

                             第三章  程序的机器级表示

  3.1 历史观点

      X86 寻址方式经历三代:

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

  3.2 程序代码

      3.2.1 机器级代码

         第一种抽象:程序的格式和行为

            ISA,指令集体系结构,定义了处理器状态,指令的格式,以及每条指令对状态的影响。

            第二种抽象:虚拟地址

            程序计数器:(IA32中称为PC,用%eip表示)

            指示将要执行的下一条指令在存储器中的地址

            整数寄存器文件包含8个命名的位置,分别存储32位的值。

            条件码寄存器保存着最近执行的算术或逻辑指令的状态信息

            一组浮点寄存器存放浮点数据

     3.2.2 代码示例

        unix> gcc -01 -S code.c 获得C语言编译器产生的汇编代码,产生一个汇编文件code.s。

           gcc -S xxx.c -o xxx.s 可以获得汇编代码。

           unix> objdump -d code.o 将二进制格式的目标代码文件反汇编成汇编语言的形式。

           汇编函数固有格式:

           function:

           push %ebp

           mov  %esp,%ebp

           .

           .

           .

           pop %ebp

           ret

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

           ubuntu 中 gcc -S code.c 也可产生代码,更接近教材(删除“.”开头的语句)

           在文件code.o上运行gdb

           (gdb) x/17xb xxx 

           告诉gdb检查17个十六进制格式的字节

           用od命令查看二进制文件:

           od code.o | more 使用more或less结合管道查看

           od code.o > code.txt 使用输出重定向查看

  3.3 数据格式

C语言声明             Intel数据类型            汇编后缀          大小(字节)
char                      字节                  b                 1
short                      字                   w                 2
int                       双字                  l                 4
long int                  双字                  l                 4
long long int              ——                   —                4
char*                     双字                  l                 4
float                    单精度                 s                  4
double                   双精度                 l                  8
long double              扩展精度               t                10/12

 

 

 

                 字节:8位                    movb

                       字(word):16位            movw

                       双字(double words):32位   movl

                       四字(quad words)

 

  3.4 访问信息

       esi edi可以用来操纵数组,esp ebp用来操纵栈帧。 

       3.4.1 操作数指示符

       1.立即数(常数)

           $-577   $0x1F

         2.寄存器

           Ea:任意寄存器a;

           R[Ea]:寄存器a的值

         3.存储器

           Mb[Addr]:对存储在存储器中从有效地址Addr开始的b个字节值的引用。

           有效地址的计算方法:

              Imm(Eb,Ei,s)= Imm+R[Eb]+R[Ei]*s

              Imm立即数偏移;

              Eb基址寄存器;

              Ei变址寄存器;

              s比例因子(s=1,2,4or8)

       3.4.2 数据传送指令

       指令                                    效果

       MOV   S,D                            D<-S

       MOVS  S,D                            D<-符号扩展(S)

       MOVZ  S,D                            D<-零扩展(S)

       pushl  S                             将双字压栈

       popl   D                             将双字出栈

    注意:不能从内存地址直接MOV到另一个内存地址,要用寄存器中转一下。

          栈“底”地址较大,栈“顶”地址较小

          指针就是地址;

          局部变量保存在寄存器中。

 

  3.5 算术和逻辑操作

     每个指令类都有对字节,字,双字的操作。这些操作被分为四组:

       加载有效地址、一元操作、二元操作和移位

       3.5.1 加载有效地址

     leal S,D           D<-&S

       例:若寄存器%edx的值为x,则

           leal 7(%edx,%edx,4),%eax  的结果为:

           将寄存器%eax的值设置为5x+7

 

     3.5.2 一元操作和二元操作

          二元操作减法:

             SUB   S,D                 D <- D-S

 

     3.5.3 移位

          移位量用单字节编码,只允许0-31位的移位。

             移位量可以是一个立即数,或者放在单字节寄存器元素%cl中。

 

  3.6 控制

      3.6.1 条件码

      当我们用add执行一条令t=a+b的指令,其中t,a,b都是整型。

        CF 进位:(unsigned) t < (unsigned) a          无符号溢出

        ZF 零  :(t==0)                             零

        SF 负数:(t<0)                              负数

        OF 溢出:(a<0==b<0)&&(t<0!=a<0)             有符号溢出

        注意:leal不改变条件码寄存器

      3.6.2 访问条件码

      条件码常见使用方法:

                          1.根据条件码的某个组合,将一个字节设置为0或者1;

                          2.条件跳转到程序的某个其他部分

                          3.有条件地传送数据

      3.6.5 循环

            1.do-while循环      

movl     8(%ebp), %edx     ;Get n
movl     $1, %eax          ;Set result = 1
.L2:                       ;loop:
imull     %edx, %eax       ;Compute result *= n
subl      $1,  %edx        ;Decrement n
cmpl     $1,  %edx         ;Compare n:1
jg         .L2             ;If >,  goto loop

  

  3.7 过程

      一个过程调用包括将数据(以过程参数和返回值的形式)和控制从代码的一部分传递到另一部分。

      同时,他必须在进入时为过程的局部变量分配空间,并在退出时释放。

       3.7.1 栈帧结构

              机器用栈来传递过程参数、存储返回信息、保存寄存器用于以后恢复,以及本地存储。

                  为单个过程分配的那部分栈称为栈帧,大多数信息的访问都是相对于帧指针的。

       3.7.2 转移控制

              call:将返回地址入栈,并跳转到被调用过程的起始处。

                  返回地址:紧跟在call后面的那条指令的地址。

                  ret:从栈中弹出返回地址,并跳转之。

                  

       3.7.3 寄存器使用惯例

             寄存器%eax、%edx和%ecx被划分为调用者保存寄存器。

                 寄存器%ebx、%esi、%edi被划分为被调用者保存寄存器。

       3.7.4 过程示例

             旁注:GCC坚持一个函数使用的所有栈空间必须是16字节的整数倍,包括保存%ebp值的4个字节和返回值的4个字节。

       3.7.5 递归过程

             递归调用自身和调用其它函数是一样的。栈规则提供了一种机制,每次函数调用都有它自己私有的状态信息存储(保存的返回位置,栈指针和被调用者保存寄存器的值)

 

 

 

 

 

 

 

               

posted on 2015-10-11 18:49  5319zl  阅读(170)  评论(2编辑  收藏  举报

导航