一、对冯·诺依曼体系结构和图灵机的理解
图灵机的理解
图灵机是为了用机器模拟人的运算过程而实现的,当图灵机从纸带(tape)上读取一个空格的信息,它就会根据控制器当前的状态和控制规则(控制规则由控制器中的program提供),改变控制器的当前状态,应该也可以改变纸带当前空格上的值,然后纸带移动一格。简单看好像以前在离散数学课上学习的状态机,用一个圆圈加数字表示当前状态,根据输入和当前状态转变为下一状态。
所谓的图灵机就是指一个抽象的机器,它有一条无限长的纸带,纸带分成了一个一个的小方格,每个方格有不同的颜色。有一个机器头在纸带上移来移去。机器头有一组内部状态,还有一些固定的程序。在每个时刻,机器头都要从当前纸带上读入一个方格信息,然后结合自己的内部状态查找程序表,根据程序输出信息到纸带方格上,并转换自己的内部状态,然后进行移动。
图灵的基本思想是用机器来模拟人们用纸笔进行数学运算的过程,他把这样的过程看作下列两种简单的动作:
- 在纸上写上或擦除某个符号;
- 把注意力从纸的一个位置移动到另一个位置;
- 而在每个阶段,人要决定下一步的动作,依赖于 (a) 此人当前所关注的纸上某个位置的符号和(b) 此人当前思维的状态。
为了模拟人的这种运算过程,图灵构造出一台假想的机器,该机器由以下几个部分组成:
1.一条无限长的纸带 TAPE。纸带被划分为一个接一个的小格子,每个格子上包含一个来自有限字母表的符号,字母表中有一个特殊的符号 表示空白。纸带上的格子从左到右依此被编号为 0,1,2,... ,纸带的右端可以无限伸展。
2.一个读写头 HEAD。该读写头可以在纸带上左右移动,它能读出当前所指的格子上的符号,并能改变当前格子上的符号。
3.一套控制规则 TABLE。它根据当前机器所处的状态以及当前读写头所指的格子上的符号来确定读写头下一步的动作,并改变状态寄存器的值,令机器进入一个新的状态。
4.一个状态寄存器。它用来保存图灵机当前所处的状态。图灵机的所有可能状态的数目是有限的,并且有一个特殊的状态,称为停机状态。
注意这个机器的每一部分都是有限的,但它有一个潜在的无限长的纸带,因此这种机器只是一个理想的设备。图灵认为这样的一台机器就能模拟人类所能进行的任何计算过程。
在某些模型中,纸带移动,而未用到的纸带真正是“空白”的。要进行的指令(q4)展示在扫描到方格之上(由 Kleene (1952) p.375 绘制)。
在某些模型中,读写头沿着固定的纸带移动。要进行的指令(q1)展示在读写头内。在这种模型中“空白”的纸带是全部为 0 的。有阴影的方格,包括读写头扫描到的空白,标记了 1,1,B 的那些方格,和读写头符号,构成了系统状态。
冯·诺依曼体系结构
虽然计算机技术发展很快,但存储程序原理至今仍然是计算机内在的基本工作原理。自计算机诞生的那一天起,这一原理就决定了人们使用计算机的主要方式——编写程序和运行程序。科学家们一直致力于提高程序设计的自动化水平,改进用户的操作界面,提供各种开发工具、环境与平台,其目的都是为了让人们更加方便地使用计算机,可以少编程甚至不编程来使用计算机,因为计算机编程毕竟是一项复杂的脑力劳动。但不管用户的开发与使用界面如何演变,存储程序控制原理没有变,它仍然是我们理解计算机系统功能与特征的基础。
说到计算机的发展,就不能不提到美籍匈牙利科学家冯·诺依曼。从20世纪初,物理学和电子学科学家们就在争论制造可以进行数值计算的机器应该采用什么样的结构。人们被十进制这个人类习惯的计数方法所困扰。所以,那时以研制模拟计算机的呼声更为响亮和有力。
20世纪30年代中期,冯·诺依曼大胆的提出,抛弃十进制,采用二进制作为数字计算机的数制基础。同时,他还说预先编制计算程序,然后由计算机来按照人们事前制定的计算顺序来执行数值计算工作。冯·诺依曼和同事们设计出了一个完整的现代计算机雏形,并确定了存储程序计算机的五大组成部分和基本工作方法。冯·诺依曼的这一设计思想被誉为计算机发展史上的里程碑,标志着计算机时代的真正开始。冯·诺依曼成功将其理论运用在计算机的设计之中,根据这一原理制造的计算机被称为冯·诺依曼结构计算机,世界上第一台冯·诺依曼式计算机是1949年研制的EDVAC,由于他对现代计算机技术的突出贡献,因此冯·诺依曼又被称为“计算机之父”,存储程序控制原理又称冯·诺依曼原理。
其理论要点如下:
- 计算机硬件设备由存储器、运算器、控制器、输入设备和输出设备5部分组成。
- 存储程序思想——把计算过程描述为由许多命令按一定顺序组成的程序,然后把程序和数据一起输入计算机,计算机对已存入的程序和数据处理后,输出结果。
- 要点是——数字计算机的数制采用二进制;计算机应该按照程序顺序执行。
根据冯·诺依曼体系结构构成的计算机,必须具有如下功能:
- 把需要的程序和数据送至计算机中。
- 必须具有长期记忆程序、数据、中间结果及最终运算结果的能力。
- 能够完成各种算术、逻辑运算和数据传送等数据加工处理的能力。
- 能够根据需要控制程序走向,并能根据指令控制机器的各部件协调操作。
- 能够按照要求将处理结果输出给用户。
为了完成上述的功能,计算机必须具备五大基本组成部件,包括:
- 输入数据和程序的输入设备
- 记忆程序和数据的存储器
- 完成数据加工处理的运算器
- 控制程序执行的控制器
- 输出处理结果的输出设备。
二、根据你的程序设计经验谈谈对“程序=指令+数据”的理解
- 指令:人为输入计算机,由计算机识别并执行一步步操作的命令的形式称为指令。
- 程序:一系列指令的有序集合称为程序。
程序在计算机中是按序执行的,CPU通过程序计数器PC控制程序的执行顺序,一般情况下程序是按序执行的,当执行转移、调用、返回等指令时,程序转移到相应的目的地址处执行。CPU根据程序计数器PC中的地址将欲执行指令的指令码从存储器中取出,存放在IR中,ID对IR中的指令码进行译码,定时控制逻辑在OSC配合下对ID译码后的信号进行分时,产生执行本条指令所需的全部信号,完成本条指令的执行。
程序分为数据和指令,以一段程序为例:
int g_date1 = 10;
int g_date2 = 0;
int g_date3;
static int g_date4 = 10;
static int g_date5 = 0;
static int g_date6 ;
int main()
{
int a = 10;
int b = 0;
int c;
static int d = 10;
static int e = 0;
static int f ;
return 0;
}
该段代码中包括全局变量和局部变量。其中全局变量又包括普通全局变量和静态全局变量,普通全局变量为:g_date1、g_date2、g_date3,静态全局变量为:g_date4、g_date5、g_date6。同样的,局部变量也分为普通局部变量和静态局部变量,普通局部变量为:a、b、c,静态局部变量为d、e、f。有些变量是初始化的,有些则没有初始化,哪些是数据,又有哪些是指令?
数据包括全局变量(包括就普通和静态两种)和静态局部变量,而指令则为普通局部变量。对可执行文件而言,存储时,初始化且值不为0的数据放在.date区(即数据段),未初始化(包括初始化为0)的数据放在.bss区,指令放在.text区。特殊的,没有被初始化的普通全局变量在编译文件中存放在.comment区,在可执行文件中存放在.bss区。
三、安全问题
缓冲区溢出
缓冲区溢出(buffer overflow)指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量,使得溢出的数据覆盖在合法数据上。缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在;利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果;可以利用它执行非授权指令,取得系统特权,进而进行各种非法操作。
- 原理
通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的。造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。例如下面程序:
void function(char *str) {
char buffer;
strcpy(buffer,str);
}
上面的strcpy()将直接把str中的内容copy到buffer中。这样只要str的长度大于16,就会造成buffer的溢出,使程序运行出错。存在象strcpy这样的问题的标准函数还有strcat(),sprintf(),vsprintf(),gets(),scanf()等。
当然,随便往缓冲区中填东西造成它溢出一般只会出现“分段错误”(Segmentation fault),而不能达到攻击的目的。最常见的手段是通过制造缓冲区溢出使程序运行一个用户shell,再通过shell执行其它命令。如果该程序有root或者suid执行权限的话,攻击者就获得了一个有root权限的shell,可以对系统进行任意操作了。
缓冲区溢出攻击之所以成为一种常见安全攻击手段其原因在于缓冲区溢出漏洞太普遍了,并且易于实现。而且,缓冲区溢出成为远程攻击的主要手段其原因在于缓冲区溢出漏洞给予了攻击者他所想要的一切:植入并且执行攻击代码。被植入的攻击代码以一定的权限运行有缓冲区溢出漏洞的程序,从而得到被攻击主机的控制权。
XSS攻击
XSS又称CSS,全称Cross SiteScript(跨站脚本攻击), XSS攻击类似于SQL注入攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性。其原理是攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的。如,盗取用户Cookie信息、破坏页面结构、重定向到其它网站等。
- 注入方式
1)xss输入通常包含JavaScript脚本,弹出恶意广告等
2)xss输入HTML代码,使网页不停地刷新,嵌入其它网站的链接 - 方法
1)输入检查,针对用户输入的数据中是否包含一些特殊字符,进行过滤
2)输出检查,HTML标签、HTML属性、script标签、事件、css、地址等中的输出
3)处理富文本,严格控制标签,使用成熟的开源框架
4)防御DOM Based XSS,从JavaScript中输出数据到html页面里
SQL注入攻击
- 简介
sql注入及时攻击者将sql命令插入到web表单的输入域或页面请求的查询字符串,欺负服务器执行恶意的sql命令 - 方法
1)验证数据,根据相应类型进行严格的验证字符,先通过sprintf函数格式化输出,再通过一些安全函数去掉一些不合法的字符,如addslashes()方法等
2)参数化绑定,PHP 中的 mysqli 和 PDO 可实现参数绑定