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

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

一 教材内容总结

信息的表示和处理

  • 计算机中三种最重要的数字表示

    • 无符号数:基于传统二进制表示法,表示大于或等于0的数字
    • 补码:编码是表示有符号数的最常见方式
    • 浮点数:表示实数的科学计数法的以2为基数的版本
    • 溢出:计算机用有限数量的位来对应一个数字编码,因此存在结果太大无法表示的状况,即溢出
  • 信息存储

    • 大多使用8位的块,字节,作为最小存储器单位
    • 地址:存储器中每一个字节都有一个唯一的数字来作为其标识
    • 虚拟地址空间:即所有可能的地址的集合
  • 十六进制表示法

    • 在实际操作过程中,存在着二进制数过于冗长复杂,而十进制数在与位模式的相互转换中非常麻烦的状态,因此采用了十六进制数来表示位模式,其基本规则即是以‘0~9’,‘ AF’来表示‘116’
    • 进制转换:十六进制与二进制之间的转换较为简单,十六进制转换成二进制只需将十六进制的每一位数按照规则转换成相应四位二进制数,二进制数逆向转换则需要按照从右往左每四位为一组划分,不足四位在左方加0补齐,之后每四位转换即可,在十进制与其他转换中存在一定不方便,只要先转换成二进制作为中间结果即可
    • 每台计算机都有字长,字长决定虚拟地址空间的最大大小
  • 数据大小

    • 不同数据类型在32位、64位机器中所占字节数不同,以c语言为例,long int&char *在32位机器中占4个字节但是在64位中占8个字节,所以同样的数据类型声明在不同位数机器上可能会导致错误
  • 寻址和字节顺序

    • 大端法和小端法:小端法即在存储器中按照最低有效字节到最高有效字节的顺序存储。大端法则反之,按照最高有效字节到最低有效字节顺序存储
  • 布尔代数

    • 掩码运算:位运算的重要运用,对于特定位可以置1,可以清零
  • 整数表示

    • 程序语言中各数据类型都有最大值以及最小值,不在范围内会发生溢出
    • c,c++支持有符号数以及无符号数,java只支持无符号数
    • 无符号数编码:例如向量x,可以写成[Xn , ... , X0]。如果把向量X看做一个二进制数,那么后者就是他的无符号表示
    • 双射:对应每一个长度为w的位向量,都有一个唯一的值来与之对应
    • 补码编码:补码最高位为符号位,其为1时,代表该数值为负,其为0时,代表该数为非负(在计算机中基本所有的有符号数都使用补码表示)
    • java中对于整数数据类型的取值范围和表示有着十分明确的标准,这是java在任何机器上都能运行表现一致的原因所在
    • c语言中允许有符号数与无符号数之间进行转换,但其原则是底层的位保持不变。且c语言中支持不同数字类型之间做强制类型转换,例如(unsigned)u可以将u转换成一个无符号数
    • 零拓展:在一个无符号数开头简答的添加0,就可以将其转换成一个更大的数据类型
    • 符号拓展:在一个有符号数表示中添加最高有效位的值的副本,将一个补码数字转换成更大的数据类型
  • 浮点数

    • 如今浮点数表示以IEEE浮点作为标准
    • IEEE浮点标准:V=(-1)s*m*2E,其中s为符号,决定该数为正数还是负数,尾数m是一个二进制小数,阶码E的作用是对浮点数加权

二 实验楼练习、问题解决过程

  • p28的代码实现

      #include "stdafx.h"
    
      typedef unsigned char *byte_pointer;
    
      void show_bytes(byte_pointer start, int len){
          int i;
          for (i = 0; i < len; i++){
      	    printf("%.2x", start[i]);
          }
          printf("\n");
      }
    
      void show_int(int x){
          show_bytes((byte_pointer)&x, sizeof(int));
      }
    
      void show_float(float x){
          show_bytes((byte_pointer)&x, sizeof(float));
      }    
    
      void show_pointer(void *x){
          show_bytes((byte_pointer)&x, sizeof(void *));
      }
    
      int _tmain(int argc, _TCHAR* argv[])
      {
          int x;
          float y;
          printf("please input a number\n");
          scanf_s("%d", &x);
          y = (float)x;
          int *z = &x;
          show_int(x);
          show_float(y);
          show_pointer(z);
          return 0;
      }
    

运行结果如下:

  • p52的代码运行修改和思考

首先随便设置一个数组a,然后计算第0个累加之和,就出现了存储器错误

在思考之后,在不修改函数的情况下,令传入参数length的值为1,仍旧出现了存储器错误

于是开始猜测错误的原因所在,length的定义为unsigned length为无符号数,而在函数中却出现了length-1,当length=0时,该值即为负数,但无符号数中无法表示负数,便对此进行修改,将i<=length-1修改为i<length

得到正确值0.0

之后继续查询,明白原因,因为参数length是无符号的,计算0-1将进行无符号运算,这等价于模数加法。结果等于UMax。所以这个比较总是真的,因此代码试图访问数组a的非法元素。

三 代码托管

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 0/0 1/1 20/20 学习常用linux命令
第二周 100/100 1/2 20/40 学习vim,gdb等用法
第三周 100/200 1/3 15/55

posted on 2016-10-02 10:56  20145319钟轲  阅读(140)  评论(1编辑  收藏  举报