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


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

    学习目标

    找出全书你认为学得最差的一章,深入重新学习一下,要求(期末占5分):
    
        总结新的收获
    
        给你的结对学习搭档讲解或请教,并获取反馈
    

    第三章程序的机器级表示

    数据格式

    由于是从16位体系结构扩展成32位,intel用术语字(word)表示16位数据类型,因此32位为双字(double words),64位数为4字(quad words)。

    以下是比较容易模糊的数据类型大小:

           32位机上:float 4    long int 4   double 8    longlong 8    char* 4   unsigned long 4
      64位机上:float 4    long int 8   double 8    longlong 8    char* 8   unsigned long 8
    
     另外,GCC 用long double表示扩展精度(10字节),出于存储器性能考虑,会被存储为12字节
    

    访问信息

    • 一个IA32 CPU包含一组8个存储32位值的寄存器,用以存整数数据和指针:eax,ecx,edx,ebx,esi,edi esp,ebp。大多数情况下前六个都用作通用寄存器,eax,ecx,edx的存储和恢复惯例不同于ebx,edi,esi(前三者为被调用者保存,后三者为调用者保存,详见3.7.3);最后两个用于存储指针,由于在过处理中非常重要,分别指向栈帧的顶部和底部,必须保持。

    操作数指示符

    大多数指令有一到多个操作数,操作数有三种:

           立即数:即常数值
    
           寄存器:表示某个寄存器内容
    
           存储器引用:根据计算出来的地址(通常称有效地址)访问某个存储器位置
    
       因此寻址方式也有多种,如:立即数寻址、寄存器寻址、绝对寻址、间接寻址、变址寻址、伸缩化  的变址寻址……
    

    数据传送指令

    几个重要数据传送指令:mov族(之所以称这为族是因为mov指令还有很多兄弟指令如movb、movw、movsb、movzb,这是我个人对它们的称呼,便于记忆mov其他几个比较低调的兄弟)、pop、push。
    
    
    
     另,对于mov族,movb、movw自不必做过多解释,movsb、movzb分别为符号扩展、零扩展,它们只拷贝一个字节,源操作数均为单字节,并设置目的操作数中其余的位,效果如下:
    
      初始假设:%dh=8D  %eax=98765432
    
      1   movb   %dh,%al       ;%eax=9876548D
    
      2   movsbl %dh,%eax    ;%eax=FFFFFF8D(目的操作数高24位设为源字节最高位,在这里为很显然为1,所以前24位为全F)
    
      3   movzbl %dh,%eax    ;%eax=0000008D(目的操作数高24位被设为0)
    
    
    
     对于pushl指令等价于:
    
          subl $4,%esp
    
          movl %ebp,(%esp)  //注意这里的括号引起的差别
    
    
    
      popl指令等价于:
    
           movl (%esp),%eax
    
           addl $4,%esp
    

        /*******C代码**********/         
        int exchange(int *xp, int y){                                 
            int x =  *xp;  
            *xp = y;  
            return x;  
        }  
          
        //*********汇编代码******/  
        //1 movl 8(%ebp),%eax   Get xp  
        //2 movl 12(%ebp),%edx  Get y  
        //3 movl (%eax),%ecx    Get x at *xp  
        //4 movl %edx,(%eax)    Store y at *xp  
        //5 movl %ecx,%eax      Set x as return value   
    
    收获
    1. 指针其实是地址,间接引用指针就是将该指针放在一个寄存器中,然后在间接存储器引用中引用这个寄存器
    2. 局部变量通常保存在寄存器中,而不是存储器

    过程

    • 一个过程调用包括将数据(以过程参数和返回值的形式)和控制从代码的一部分传递到另一部分。另外,它还必须在进入时为过程的局部变量分配空间,并在退出时释放这些空间。
    栈帧结构
    • 栈帧结构指的是为单个过程分配的那部分栈。栈帧的最顶端是以两个指针定界的,寄存器%ebp作为帧指针,寄存器%esp作为栈指针。栈指针是可以移动的,所以大多数信息的访问都是相对于帧指针的 。
    转移控制

    call :过程调用

    leave:为返回准备栈

    ret:从过程调用中返回

    递归过程

    错题总结



    家庭作业

    3.59
    • 这个题考察的是2.3.4和2.3.5节的一个定理:w比特长度的两个数相乘,会产生一个2w长度的数,不管这两个数是无符号数还是补码表示的有符号数,把结果截取的低w比特都是相同的。

    所以我们可以用无符号数乘法指令mulq实现有符号数乘法:先把数有符号扩展致2w位,然后把这两个2w位的数相乘,截取低2w位即可。

    截取就是求模运算,即 mod 2^w。

    store_prod
        movq    %rdx, %rax      #rax中保存y
        cqto                    #将rax有符号扩展为rdx:rax,即rdx为全1
        movq    %rsi, %rcx      #rcx中保存x
        sarq    $63, %rcx       #rcx为为全1若x小于0,否则为0,即将x有符号扩展
        #下面把这两个扩展的数当成无符号数进行运算,取低128bit。
        #此时y表示为rdx:rax,x表示为rcx:rsi, 即y = rdx*2^64 + rax, x = rcx*2^64 + rsi
        #x*y = rdx*rcx*2^128 + rdx*rsi*2^64 + rcx*rax*2^64 + rax*rsi
        #由于我们只需要取低128位,所以对x*y进行取模操作mod 128,得到公式:rdx*rsi*2^64mod2^128 + rcx*rax*2^64mod2^128 + rax*rsi
        #由于这里的寄存器都是64位的,所以对于rdx*rsi*2^64mod2^128这样的操作我们可以直接使用imulq指令,截取两个寄存器相乘的低64位,然后把他加到rax*rsi的高64位。
        #下面实现公式
        imulq   %rax, %rcx      #rcx*rax*2^64mod2^128(随后放在高64位)
        imulq   %rsi, %rdx      #rdx*rsi*2^64mod2^128(随后放在高64位)
        addq    %rdx, %rcx      #随后放在高64位
        mulq    %rsi            #x*y即rax*rsi
        addq    %rcx, %rdx      #放在高64位
        movq    %rax, (%rdi)    #存储低64位
        movq    %rdx, 8(%rdi)   #存储高64位
        ret
    
  • 相关阅读:
    python学习的第六天数据类型及内置方法part2
    作业5
    Python学习第五天基本数据类型及内部方法part1
    周作业
    作业
    python学习第四天控制流程if、while、for
    作业
    python学习第三天基本数据类型、格式化输入输出、运算符。流程控制
    从排序数组中删除重复项
    D3.js 比例尺
  • 原文地址:https://www.cnblogs.com/hpl20155329/p/8099359.html
Copyright © 2020-2023  润新知