20155208《信息安全系统设计基础》第十三周学习总结

学习任务

  • 找出全书你认为最重要的一章,深入重新学习一下,要求
  • 完成这一章所有习题
  • 详细总结本章要点
  • 给你的结对学习搭档讲解你的总结并获取反馈

重新学习第二章内容

我认为无论是什么学科,只有打好基础,才能进行更深一步的学习与理解,所以我决定重新着重学习第二章的内容:信息的表示与处理。

第二章教材内容学习总结

  • 一个字节由8位组成
  • 在C语言中,以Ox和OX开头的数字常量被认为是十六进制的值。
  • 其他进制表示法:二进制(B),十进制(D),八进制(O或者Q),十六进制(H)
  • 三中重要的数字表示

无符号[表示大于或等于零的数字]

补码[二进制补码][表示有符号整数]

浮点数[表示实数的科学计数法的以二为基数的版本]

  • 进制转换

进制转换,注意拿二进制作中间结果就好转了 数据大小

gcc -m32 可以在64位机上(比如实验楼的环境)生成32位的代码

  • 寻址和字节顺序

最低有效字节在最前面的方式,小端法

最高有效字节在最前面的方式,大端法

进行书上练习2.4

习题总结: 注意进行十六进制加减法时的进位和退位时每个单位是以16的n次幂为基础进行的。

  • 理论来说,对于一个字长为w位的机器来说,虚拟地址的范围是0~2w-1。程序最多访问2w个字节。
  • C语言支持整数和浮点数的多种数据格式。
  • 在几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址为使用地址中最小的地址。
  • C语言中的typedef声明提供了一种给数据类型命名的方式。这能极大地改善代码的可读性,因为深度嵌套的类型声明很难读懂。它使用的是类型名而不是变量名,eg:
typedef int *int_pointer;
int_pointer ip;
  • Linux 32、Windows和Sun的机器使用的是4字节地址,而Linux 64使用的是8字节地址。
  • 运行书上代码 实现交换功能
#include<stdio.h>
#define Max 10
void inplace_swap(int *x,int *y)
	{
	*y = *x^*y;
	*x = *x^*y;
	*y = *x^*y;
}
void reverse_array(int a[],int cnt)
	{
	 int first,last;
	 for(first = 0,last =cnt-1;
	       first<=last;
	       first++,last--)
	inplace_swap(&a[first],&a[last]);
	}
void main()
{
int MAX;
int a[MAX];
int count,i;
printf("please enter the amount of numbers(no more %d):\n",MAX);
scanf("%d",&count);
printf("please enter any numbers as the end\n");
for(i = 1;i<=count;i++)
{
	scanf("%d\n",&a[i-1]);
}
printf("the original array is as follow:\n");
for(i = 1;i<=count;i++)
{
printf("%d ",a[i-1]);
}
reverse_array(a, count);
printf("the new array is as follow:\n");
for(i = 1;i<=count;i++)
{printf("%d ",a[i-1]);
}
}

进行书上练习2.6

习题总结: 熟悉十六进制与二进制之间的转换,并且了解什么叫做匹配位数。

  • 表示字符串和代码: C语言中字符串被编码为一个null字符结尾的字符数组。每个字符串都由某个标准编码来表示,最常见的是ASCII字符码。
  • 通过执行命令 man ascii ,你可以得到一张ASCII字符码的表。
  • 布尔代数 常用运算符号:与 :& 或 :| 非:~ 异或:^

进行书上练习2.8

  • 位级运算:位向量按位进行逻辑运算,结果仍是位向量。位级运算的一个常见用法就是实现掩码运算,这里掩码是一个位模式,表示从一个字中选出的为的集合。

  • C语言中的移位运算: C语言标准并没有明确定义应该使用那种两类型的右移。对于无符号数据,右移必须是逻辑的。而对于有符号数据,算术的或者逻辑的右移都可以。

  • 所有逻辑运算都可以用与、或、非表达(最大式、最小式),而与或非可以用“与非”或“或非”表达,所以,只要一个与非门,就可以完成所有的逻辑运算。

  • 掩码是位运算的重要应用,对特定位可以置一 ,可以清零。

  • 掩码是一个位模式,表示从一个字中选出的位的集合。

  • 用位向量给集合编码,通过指定掩码来有选择的屏蔽或者不屏蔽一些信号,比如某一位位置上为1时,表明信号i是有效的;0表示该信号被屏蔽。

#include<stdio.h>

#define Max 10

int  optarith(int x,int y);

void main()

{

int MAX;

int a[MAX];

int count,i;

printf("please enter the amount of numbers(no more %d):\n",MAX);

scanf("%d",&count);

printf("please enter any numbers as the end\n");

for(i = 1;i<=count;i++)

{

	scanf("%d\n",&a[i-1]);

}

printf("the original optarith is as follow:\n");

for(i = 1;i<=count;i++)

{

printf("%d ",a[i-1]);

}

reverse_array(a, count);

printf("the new optarith is as follow:\n");

for(i = 1;i<=count;i++)

{printf("%d ",a[i-1]);

}

}

int  optarith(int x,int y){

	int x = 0;

	x<<=5;

	x-=t;

	if(y<0)y+=7;

	y>>=3;

	return x+y;

}

  • 整型数据类型

要用C99中的“long long”类型,编译是要用 gcc -std=c99。long long至少需要8个字节表示。

补码的利用寄存器的长度是固定的特性简化数学运算。想想钟表,12-1 等价于 12 + 11,利用补码可以把数学运算统一成加法,只要 一个加法器就可以实现所有的数学运算。

注意C语言中有符号数和无符号数的转换规则,位向量不变。

进行书上练习2.10、2.11

在虚拟机上进行代码编写,并回答问题。

  • c语言中的移位运算右移

右移分为逻辑右移和算术右移。算术左移和逻辑左移没有什么区别。逻辑右移: 在左端补k个0,多用于无符号数移位运算算术右移: 在左端补k个最高有效位的值,多用于有符号数移位运算。

  • 补码运算

补码的用法: 加法必须确定结果太大或者太小时,应该采取什么措施,两个数的w位补码之和与无符号数之和有完全相同的位级表示。大部分计算机使用同样的机器指令来执行无符号或者有符号加法。

  • 根据阶码的值,被编码的值可分为三种:

一:规格化的值(当阶码字段不全为0或全为1时),阶码E = e-Bias(e为无符号整数);偏置值 Bias = 2^(k-1)-1;尾数M = 1+f(小数字段frac的解释为描述小数值f,二进制小数点在小数字段最高有效位的左边)。

二:非规格化的值 (当阶码字段全为0时),E = 1-Bias;Bias = 2^(k-1)-1;M = f

三:特殊值 (当阶码字段全为1时),当小数域全为0时, 当s=1时,为-∞;当s=0时,为+∞;当小数域不全为0时,为NaN

  • 向偶数舍入,也称为向最接近的值舍入,是默认的方式,方法是:将数字向上或者向下舍入,使得结果的最低有效数字是偶数。

  • 注意:-1和UMax有同样的位表示——全1的串。数值0在两种表示方式中都是全0的串。

  • 0扩展和符号扩展

零扩展:简单地在表示的开头添加0;

符号扩展:在表示中添加最高有效位的值的副本。

  • 浮点数有科学计数法的基础就不难理解,IEEE标准754

  • 浮点数运算的不精确性与舍入

    IEEE浮点标准,float/double类型

    IEE浮点标准: 用V=(-1)^s X 2^E X M 来表示一个数

  • 符号:s决定这个数是正还是负。0的符号位特殊情况处理。

  • 阶码:E对浮点数加权,权重是2的E次幂(可能 为负数)

  • 尾数:M是一个二进制小数,范围为12-ε或者01-ε(ε=1/2的n次幂)

  • 编码规则:单独符号位s编码符号s,占1位
    k位的阶码字段exp编码阶码E

    n位小数字段frac编码尾数M(同时需要依赖阶码字段的值是否为0)

单精度(float),k=8位,n=23位,一共32位;

双精度(double),k=11位,n=52位,一共64位。 一些位运算的常见技巧

0 ^ a = a

    a ^ a = 0

    a & (a - 1)可以消除最右边的一个1

    位运算x & 0xFF生成一个由x的最低有效字节组成的值,而其他字节就被置为0。

    Java是用的补码,0x7fffffff是最大正整数,0x80000000是最小的负数。和0x7fffffff按位与就是取绝对值了,然后那个按位或就是求负数。

    可以用if ((a & 1) == 0)代替if (a % 2 == 0)来判断a的奇偶性。

    修改正负号就是按位取反再加一,也就是~x + 1

    检验补码乘法是否溢出:
    int p = x * y;
    return !x || p / x == y;

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

问题: 教材中的练习2.34 对补码x[110]与y[110]的乘积结果[000100]的计算问题。

解决过程: 首先要了解补码乘法,然后进行了如下运算:

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

问题: 运行书上35页的两个代码,刚开始运行不了,然后自己加了一个主函数,还是有错误,错误信息如下:

解决过程: 在加了一个主函数后,定义了MAX常量,后成功运行:

代码托管截图

码云链接

结对对象收获反馈

结伴对象博客链接20145337方浩南

解决同伴在学习中遇到的问题:

问题: 为什么汇编中有两个分支呢?

解决过程: 第一个条件分支是&&表达式实现的一部分;如果对p为非空的测试失败,代码会跳过对a>0的测试。

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

这次的博客是自己选一章觉得重要的内容进行再一次学习,所以这次的学习就要更加的深入,更加的详细,将上次遗留的问题进行解决,这次的收获也特别大,而且这次也和接伴对象一起学习,互相解决了彼此的问题。