weitom1982

向各位技术前辈学习,学习再学习.
posts - 299, comments - 79, trackbacks - 0, articles - 0
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

 

大学课程为什么要开设编译原理呢?这门课程关注的是编译器方面的产生原理和技术问题,似乎和计算机的基础领域不沾边,可是编译原理却一直作为大学本科的必修课程,同时也成为了研究生入学考试的必考内容。编译原理及技术从本质上来讲就是一个算法问题而已,当然由于这个问题十分复杂,其解决算法也相对复杂。我们学的数据结构与算法分析也是讲算法的,不过讲的基础算法,换句话说讲的是算法导论,而编译原理这门课程讲的就是比较专注解决一种的算法了。在20世纪50年代,编译器的编写一直被认为是十分困难的事情,第一Fortran的编译器据说花了18年的时间才完成。在人们尝试编写编译器的同时,诞生了许多跟编译相关的理论和技术,而这些理论和技术比一个实际的编译器本身价值更大。就犹如数学家们在解决著名的哥德巴赫猜想一样,虽然没有最终解决问题,但是其间诞生不少名著的相关数论。

推荐参考书

虽然编译理论发展到今天,已经有了比较成熟的部分,但是作为一个大学生来说,要自己写出一个像Turboc C,Java那样的编译器来说还是太难了。不仅写编译器困难,学习编译原理这门课程也比较困难。

正是因为编译原理学习相对困难,那么就要求有好的教师和好的教材。教师方面不是我们能自己更改的,而在教材方面我们却可以按自己的意愿来阅读。我下面推荐几本好的编译原理的教材。我推荐的书籍都是国外的经典教材,因为在国内的教材中,确实还没发现什么让人满意的。

第一本书的原名叫《Compilers Principles,Techniques,and Tools》,另外一个响亮的名字就是龙书。原因是这本书的封面上有条红色的龙,也因为獗臼樵诒嘁朐?砘?×煊蛉肥堤?忻???所以很多国外的学者都直接取名为龙书。最近机械工业出版社已经出版了此书的中文版,名字就叫《编译原理》。该书出的比较早,大概是在85或86年编写完成的,作者之一还是著名的贝尔实验室的科学家。里面讲解的核心编译原理至今都没有变过,所以一直到今天,它的价值都非凡。这本书最大的特点就是一开始就通过一个实际的小例子,把编译原理的大致内容罗列出来,让很多编译原理的初学者很快心里有了个底,也知道为什么会有这些理论,怎么运用这些理论。而这一点是我感觉国内的教材缺乏的东西,所以国内的教材都不是写给愿意自学的读者,总之让人看了半天,却不知道里面的东西有什么用。

第二本书的原名叫《Modern Compiler Design》,中文名字叫做《现代编译程序设计》。该书由人民邮电出版社所出。此书比较关注的是编译原理的实践,书中给出了不少的实际程序代码,还有很多实际的编译技术问题等等。此书另外一个特点就是其“现代”而字。在传统的编译原理教材中,你是不可能看到如同Java中的“垃圾回收”等算法的。因为Java这样的解释执行语言是在近几年才流行起来的东西。如果你想深入学习编译原理的理论知识,那么你肯定得看前面那本龙书,如果你想自己动手做一个先进的编译器,那么你得看这本《现代编译程序设计》。

第三本书就是很多国内的编译原理学者都推荐的那本《编译原理及实践》。或许是这本书引入国内比较早吧,我记得我是在高中就买了这本书,不过也是在前段时间才把整本书看完。此书作为入门教程也的确是个不错的选择。书中给出的编译原理讲解也相当细致,虽然不如前面的龙书那么深入,但是很多地方都是点到为止,作为大学本科教学已经是十分深入了。该书的特点就是注重实践,不过感觉还不如前面那本《现代编译程序设计》的实践味道更重。此书的重点还是在原理上的实践,而非前面那本那样的技术实践。《编译原理及实践》在讲解编译原理的各个部分的同时,也在逐步实践一个现代的编译器Tiny C.等你把整本书看完,差不多自己也可以写一个Tiny C了。作者还对Lex和Yacc这两个常用的编译相关的工具进行了很详细的说明,这一点也是很难在国内的教材中看到的。

推荐了这三本教材,都有英文版和中文版的。很多英文好的同学只喜欢看原版的书,不我的感觉是这三本书的翻译都很不错,没有必要特别去买英文版的。理解理论的实质比理解表面的文字更为重要。

编译原理的实质

前面已经说过,学习编译原理其实也就是学习算法而已,没什么特别的。只不过这些算法的产生已经形成了一套理论。下面我来看看编译原理里面到底有什么高深的理论吧。

几乎每本编译原理的教材都是分成词法分析,语法分析(LL算法,递归下降算法,LR算法),语义分析,运行时环境,中间代码,代码生成,代码优化这些部分。其实现在很多编译原理的教材都是按照85,86出版的那本龙书来安排教学内容的,所以那本龙书的内容格式几乎成了现在编译原理教材的定式,包括国内的教材也是如此。一般来说,大学里面的本科教学是不可能把上面的所有部分都认真讲完的,而是比较偏重于前面几个部分。像代码优化那部分东西,就像个无底洞一样,如果要认真讲,就是单独开一个学期的课也不可能讲得清楚。所以,一般对于本科生,对词法分析和语法分析掌握要求就相对要高一点了。

词法分析相对来说比较简单。可能是词法分析程序本身实现起来很简单吧,很多没有学过编译原理的人也同样可以写出各种各样的词法分析程序。不过编译原理在讲解词法分析的时候,重点把正则表达式和自动机原理加了进来,然后以一种十分标准的方式来讲解词法分析程序的产生。这样的做法道理很明显,就是要让词法分析从程序上升到理论的地步。

语法分析部分就比较麻烦一点了。现在一般有两种语法分析算法,LL自顶向下算法和LR自底向上算法。LL算法还好说,到了LR算法的时候,困难就来了。很多自学编译原理的都是遇到LR算法的理解成问题后就放弃了自学。其实这些东西都是只要大家理解就可以了,又不是像词法分析那样非得自己写出来才算真正的会。像LR算法的语法分析器,一般都是用工具Yacc来生成,实践中完全没有比较自己来实现。对于LL算法中特殊的递归下降算法,因为其实践十分简单,那么就应该要求每个学生都能自己写。当然,现在也有不少好的LL算法的语法分析器,不过要是换在非C平台,比如Java,Delphi,你不能运用YACC工具了,那么你就只有自己来写语法分析器。

等学到词法分析和语法分析时候,你可能会出现这样的疑问:“词法分析和语法分析到底有什么?”就从编译器的角度来讲,编译器需要把程序员写的源程序转换成一种方便处理的数据结构(抽象语法树或语法树),那么这个转换的过程就是通过词法分析和语法分析的。其实词法分析并非一开始就被列入编译器的必备部分,只是我们为了简化语法分析的过程,就把词法分析这种繁琐的工作单独提取出来,就成了现在的词法分析部分。除了编译器部分,在其它地方,词法分析和语法分析也是有用的。比如我们在DOS,Unix,Linux下输入命令的时候,程序如何分析你输入的命令形式,这也是简单的应用。总之,这两部分的工作就是把不“规则”的文本信息转换成一种比较好分析好处理的数据结构。那么为什么编译原理的教程都最终把要分析的源分析转换成“树”这种数据结构呢?数据结构中有Stack, Line,List…这么多数据结构,各自都有各自的特点。但是Tree这种结构有很强的递归性,也就是说我们可以把Tree的任何结点Node提取出来后,它依旧是一颗完整的Tree。这一点符合我们现在编译原理分析的形式语言,比如我们在函数里面使用函树,循环中使用循环,条件中使用条件等等,那么就可以很直观地表示在Tree这种数据结构上。同样,我们在执行形式语言的程序的时候也是如此的递归性。在编译原理后面的代码生成的部分,就会介绍一种堆栈式的中间代码,我们可以根据分析出来的抽象语法树,很容易,很机械地运用递归遍历抽象语法树就可以生成这种指令代码。而这种代码其实也被广泛运用在其它的解释型语言中。像现在流行的Java,.NET,其底层的字节码bytecode,可以说就是这中基于堆栈的指令代码的。

关于语义分析,语法制导翻译,类型检查等等部分,其实都是一种完善前面得到的抽象语法树的过程。比如说,我们写C语言程序的时候,都知道,如果把一个浮点数直接赋值给一个整数,就会出现类型不匹配,那么C语言的编译器是怎么知道的呢?就是通过这一步的类型检查。像C++语言这中支持多态函数的语言,这部分要处理的问题就更多更复杂了。大部编译原理的教材在这部分都是讲解一些比较好的处理策略而已。因为新的问题总是在发生,旧的办法不见得足够解决。

本来说,作为一个编译器,起作用的部分就是用户输入的源程序到最终的代码生成。但是在讲解最终代码生成的时候,又不得不讲解机器运行环境等内容。因为如果你不知道机器是怎么执行最终代码的,那么你当然无法知道如何生成合适的最终代码。这部分内容我自我感觉其意义甚至超过了编译原理本身。因为它会把一个计算机的程序的运行过程都通通排在你面前,你将来可能不会从事编译器的开发工作,但是只要是和计算机软件开发相关的领域,都会涉及到程序的执行过程。运行时环境的讲解会让你更清楚一个计算机程序是怎么存储,怎么装载,怎么执行的。关于部分的内容,我强烈建议大家看看龙书上的讲解,作者从最基本的存储组织,存储分配策略,非局部名字的访问,参数传递,符号表到动态存储分配(malloc,new)都作了十分详细的说明。这些东西都是我们编写平常程序的时候经常要做的事情,但是我们却少去探求其内部是如何完成。

关于中间代码生成,代码生成,代码优化部分的内容就实在不好说了。国内很多教材到了这部分都会很简单地走马观花讲过去,学生听了也只是作为了解,不知道如何运用。不过这部分内容的东西如果要认真讲,单独开一学期的课程都讲不完。在《编译原理及实践》的书上,对于这部分的讲解就恰到好处。作者主要讲解的还是一种以堆栈为基础的指令代码,十分通俗易懂,让人看了后,很容易模仿,自己下来后就可以写自己的代码生成。当然,对于其它代码生成技术,代码优化技术的讲解就十分简单了。如果要仔细研究代码生成技术,其实另外还有本叫做《Advance Compiler Desgin and Implement》,那本书现在由机械工业出版社引进的,十分厚重,而且是英文原版。不过这本书我没有把它列为推荐书给大家,毕竟能把龙书的内容搞清楚,在中国已经就算很不错的高手了,到那个时候再看这本《Advance Compiler Desgin and Implement》也不迟。代码优化部分在大学本科教学中还是一个不太重要的部分,就是算是实践过程中,相信大家也不太运用得到。毕竟,自己做的编译器能正确生成执行代码已经很不错了,还谈什么优化呢?

关于实践

编译原理的课程毕竟还只是讲解原理的课程,不是专门的编译技术课程。这两门课程是有很大的区别的。编译技术更关注实际的编写编译器过程中运用到的技术,而原理的课关注讲解其基本理论。但是计算机科学本身就是一门实践性很强的课程,如果能够学以致用,那才叫真正的学会。李阳在讲解疯狂英语的时候就说到,只要当你会实际中运用一个单词一个词组的时候你才能叫学会了这个单词或者词组,而不是只是知道了它的拼写和意思。其实任何学习都是一样的,如果缺少了实践的结合,你不能算学会。

编译原理的课程主要就是讲解编译器产生的理论和原理,那么很简单,自己写个编译器就是最好的实践过程了。不过你得小心,编译系统可能是所有软件系统中最复杂的系统之一,不然为什么大学里面还会把编译器的编写开成一门叫做编译原理的课程来讲?我很佩服那些学了操作系统原理就开始自己写操作系统,学了编译原理就开始自己写编译器的人们,确实,在中国,敢这么做的学生太少了。且不管你这样做能不能做成功,至少有了这个尝试,会让你的程序设计,系统规划安排的功底增进不少。我下面给出一些关于实践过程中可能会遇到的困难,希望能够在你陷入困境的前帮你一把。

1. Lex和Yacc. 这两工具是作为词法分析很语法分析的工具。如果你自己写一个编译器,我十分不建议你连词法分析这种事情都亲手来写。Lex和Yacc应该是作为每本编译原理的教材的必备内容,可是在国内的教材中缺很少看到。这两个工具是Unix系统下的小东西,如果你要在Windows中运用,那么你最好去下在cygwin这个软件。它是个在Windows下模拟Unix的东东,里面就包含了flex.exe和bison.exe(yacc)这两个工具.这两个工具使用起来还挺麻烦的(其实unix 下的很多十分有用的工具都是这样), 不过在《编译原理与实践》这本书上对于这两个工具的讲解十分详细,还列举了不少实际的例子。

2. 做解释型语言比做生成机器代码的编译器简单。虽然说,做解释型的编译器,像Java那样的,你还得自己去写解释器,不过这样你就不必去查找机器代码的资料了。如果你做生成的最终机器代码编译器可能会遇到问题还有就是寄存器为基础的代码生成方法。前面说过,如果你生成的是以堆栈为基础的代码,那么其代码生成过程十分简单,需要考虑的东西也不多,如果你考虑最终的机器代码生成的话,你必须考虑机器的寄存器如何分配等麻烦的问题。

3. 考虑用别人已经生成的语法文件,尽量不要自己动手写词法文件和语法文件.以前一个朋友曾经说过,写出一个好的程序语言的语法定义,就几乎完成了一个编译器的一半.确实是这样,语法文件的编写是个很难的事情.现在网上到处都可以找到比如C语言,C++,Java, Tiny C,Minus C等语言的词法文件和语法文件,你完全可以自己下下来来用.

在《编译原理及实践》的书中,作者给出了一个Tiny C的全部代码.我自我感觉作者的这个编译器做得很不错,相对于其它php,perl等语言的源代码来说,简单得多,容易看懂,而且很清晰地展现了一个完成的编译系统的实现过程.其源代码可以在作者的网站上下载

posted @ 2007-01-23 13:08 高山流水 阅读(612) | 评论 (0)编辑 收藏

QUOTE
作者:伊梅 本文选自:开放系统世界——赛迪网 2002年10月10日


自由软件社区是一个充满自由和梦想的地方,在10余年的时间里它创造了一个又一个奇迹。然而,这些奇迹的创造者不只是Stallman,也不只是Linus Torvalds,而是活跃在世界各地的不计其数的开发人员。

在使用各种功能强大的自由软件时,我总会对其开发者充满崇敬之情,期盼有朝一日自己也能成为他们中的一员。很多对自由社区充满向往之情的人,虽然也想努力融身于其中,但又不知该怎么做。那么,就请与我们一起从编写一个简单的操作系统开始吧!


我们要做的事情


有人可能担心自己既没有学过计算机原理,也没有学过操作系统原理,更不懂汇编语言,对C语言也一知半解,能写操作系统吗?答案是没问题。我将带大家一步一步完成自己的操作系统。当然如果学一学上述内容再好不过。

首先要明确处理器(也就是CPU)控制着计算机。对PC而言,启动的时候,CPU都处在实模式状态,相当于只是一个Intel 8086处理器。也就是说,即使你现在拥有一个奔腾处理器,它的功能也只能是8086级别。从这一点上来讲,可以使用一些软件把处理器转换到著名的保护模式。只有这样,我们才可以充分利用处理器的强大功能。

编写操作系统开始是对BIOS控制,取出存储在ROM里的程序。BIOS是用来执行POST(Power On Self Test,自检)的。自检是检查计算机的完整性(比如外设是否工作正常、键盘是否连接等)。这一切完成以后,你就会听到PC喇叭发出一声清脆的响声。如果一切正常,BIOS就会选择一个启动设备,并且读取该设备的第一扇区(即启动扇区),然后控制过程就会转移到指定位置。启动设备可能是一个软盘、光盘、硬盘,或者其它所选择的设备。在此我们把软盘作为启动设备。如果我们已经在软盘的启动扇区里写了一些代码,这时它就被执行。因此,我们的目的很明确,就是往软盘的启动扇区写一些程序。

首先使用8086汇编来写一个小程序,然后将其拷贝至软盘的启动扇区。为了实现拷贝,要写一个C程序。最后,使用软盘启动计算机。


需要的工具


● as86:这是一个汇编程序,它负责把写的代码转换成目标文件。

● ld86:这是一个连接器,as86产生的目标代码由它来转换成真正的机器语言。机器语言是8086能够解读的形式。

● GCC:著名的C编程器。因为我们需要写一个C程序将自己的OS转移到软盘中。

● 一张空软盘:它用于存储编写的操作系统,也是启动设备。

● 一台装有Linux的计算机:这台机器可以很旧,386、486都可以。

在大部分标准Linux发行版中都会带有as86和ld86。在我使用的Red Hat 7.3中就包含有这两个工具,并且在默认的情况下,它已经安装在机器里。如果使用的Linux没有这两个工具,可以从网上下载(http://www.cix.co.uk/~mayday/),这两个工具都包含在一个名为bin86的软件包中。此外,有关的文档也可以在网上获得(www.linux.org/docs/ldp/howto/Assembly-HOWTO/as86.html)。


开始工作


使用一个你喜欢的编辑器输入以下内容:

entry start
start:
      mov ax,#0xb800
      mov es,ax
      seg es
      mov [0],#0x41
      seg es
      mov [1],#0x1f
loop1: jmp loop1

 

这是as86可以读懂的一段汇编程序。第一个句子指明了程序的入口点,声明整个过程从start处开始。第二行指明了start的位置,说明整个程序要从start处开始执行。0xb800是显存的开始地址。#表明其后是一个立即数。执行语句:

mov ax,#oxb800

 

ax寄存器的值就变为0xb800,这就是显存的地址。下面再将这个值移至es寄存器,es是附加段寄存器。请记住8086有一个分段的体系结构。它的各段寄存器为代码段、数据段、堆栈段和附加段,对应的寄存器名称分别为cs、ds、ss和es。事实上,我们把显存地址送入了附加段,因此,任何送入附加段的东西都会被送到显存中。

要在屏幕上显示字符,就需要向显存中写两个字节。前一个是所要显示字符的ASCⅡ值,第二个字节表示该字符的属性。属性包括字符的前景色、背景色及是否闪烁等等。seg es指明下一个将要执行的指令是指向es段的。所以,我们把值0x41(在ASCⅡ中表示的字符是A)送到显存的第一个字节中。接下来要把字符的属性送到下一个字节当中。在此输入的是0x1f,该属性指的是在蓝色背景下显示白色的字符。因此,如果执行这个程序,就可以在屏幕上得到显示在蓝底上的一个白色的A。接着是一个循环。因为在执行完显示字符的任务后,要么让程序结束,要么使用一个循环使其永远运行下去。把该文件命名为boot.s,然后存盘。

此处显存的概念说得不是很清楚,有必要进一步解释一下。假设屏幕由80列×25行组成,那么第一行就需要160字节,其中一个字节用于表示字符,另外一个字节用于表示字符的属性。如果要在第三行显示某一字符的话,就要跳过显存的第0和1字节(它们是用于显示第1列的),第2和3字节(它们是用于显示第2列的),然后把需要显示字符的ASCⅡ码值入第4字节,把字符的属性写入第5字节。


把程序写至启动扇区


下面写一个C程序,把我的操作系统写入软盘第一扇区。程序内容如下:

#include  /* unistd.h 需要这个文件 */
#include     /* 包含有read和write函数 */
#include
int main()
{
  char boot_buf[512];
   int floppy_desc, file_desc;
  file_desc = open("./boot", O_RDONLY);
  read(file_desc, boot_buf, 510);
  close(file_desc);
  boot_buf[510] = 0x55;
  boot_buf[511] = 0xaa;
  floppy_desc = open("/dev/fd0", O_RDWR);
  lseek(floppy_desc, 0, SEEK_CUR);
  write(floppy_desc, boot_buf, 512);
  close(floppy_desc);
}

 

首先,以只读模式打开boot文件,然后在打开文件时把文件描述符复制到file_desc变量中。从文件中读取510个字符,或者读取直到文件结束。在本例中由于文件很小,所以是读取至文件结束。然后关闭文件。

最后4行代码打开软盘驱动设备(一般来说是/dev/fd0)。使用lseek找到文件开始处,然后从缓冲中向软盘写512个字节。

在read、write、open和lseek的帮助页中,可以看到与函数所有有关的参数及其使用方法。程序中有两行比较难懂:

boot_buf[510] = 0x55;
boot_buf[511] = 0xaa;

 

该信息是用于BIOS的,如果它识别出该设备是一个可启动的设备,那么在第510和511的位置,该值就应该是0x55和0xaa。程序会把文件boot读至名为boot_buf的缓冲中。它要求改变第510和第511字节,然后把boot_buf写至软盘之上。如果执行代码,软盘上的前512字节就包含了启动代码。最后,把文件存为write.c。


编译运行


使用下面的命令把文件变为可执行文件:

as86 boot.s -o boot.o
ld86 -d boot.o -o boot
cc write.c -o write

 

首先将boot.s文件编译成目标文件boot.o,然后将该文件连接成最终的boot文件。最后C程序编译成可执行的write文件。

插入一个空白软盘,运行以下程序:

./write

 

重新启动电脑,进行BIOS的界面设置,并且把软盘设为第一个启动的设备。然后插入软盘,电脑从软盘上启动。

启动完成后,在屏幕上可以看到一个字母A(蓝底白字),启动速度很快,几乎是在瞬间完成。这就意味着系统已经从我们制作的软盘上启动了,并且执行了刚才写入启动扇区的程序。现在,它正处在一个无限循环的状态。所以,如果想进入Linux,必需拿掉软盘,并且重启机器。

至此,这个操作系统就算完成了,虽然它没有实现什么功能,但是它已经可以启动机器了
上一期,我讲述了如何在软盘的启动扇区写一些代码,然后再从软盘启动的过程。制作好一个启动扇区,在切换到保护模式之前,我们还应该知道如何使用BIOS中断。BIOS中断是一些由BIOS提供的、为了使操作系统的创建更容易的低级程序。在本文中,我们将学习处理BIOS的中断。


为什么要用BIOS


BIOS会把启动扇区拷贝至RAM中,并且执行这些代码。除此之外,BIOS还要做很多其它的事情。当一个操作系统刚开始启动时,系统中并没有显卡驱动、软盘驱动等任何驱动程序。因此,启动扇区中不可能包含任何一个驱动程序,我们要采取其它的途径。这个时候,BIOS就可以帮助我们了。BIOS中包含有各种可以使用的程序,包括检测安装的设备、控制打印机、计算内存大小等用于各种目的的程序。这些程序就是所说的BIOS中断。


如何调用BIOS中断


在一般的程序设计语言中,函数的调用是一件非常容易的事情。比如在C语言中,如果有一个名为display的程序,它带有两个参数,其中参数noofchar表示显示的字符数,参数attr表示显示字符的属性。那么要调用它,只需给出程序的名称即可。对于中断的调用,我们使用的是汇编语言中的int指令。

比如,在C语言中要显示一些东西时,使用的指令如下所示:

display(nofchar,attr);


而使用BIOS时,要实现相同功能使用的指令如下:

int 0x10


如何传递参数


在调用BIOS中断之前,我们需要先往寄存器中送一些特定的值。假设要使用BIOS的中断13h,该中断的功能是把数据从软盘传送至内存之中。在调用该中断之前,要先指定拷贝数据的段地址,指定驱动器号、磁道号、扇区号,以及要传送的扇区数等等。然后,就要往相应的寄存器送入相应的值。在进行下面的步骤前,读者有必要对这一点有比较明确地认识。

此外,一个比较重要的事实是同一个中断往往可以实现各种不同的功能。中断所实现的确切功能取决于所选择的功能号,功能号一般都存在ah寄存器之中。比如中断13h可以用于读磁盘、写磁盘等功能,如果把3送入ah寄存器中,那么中断选择的功能就是写磁盘;如果把2送入ah寄存器中,选择的功能则是读磁盘等。


我们要做的事情


这次我们的源代码由两个汇编语言程序和一个C程序组成。第一个汇编文件是引导扇区的代码。在引导扇区中,我们写的代码是要把软盘中第二扇区拷贝至内存段的0x500处(地址是0x5000,即偏移地址为0)。这时我们需要使用BIOS的中断13h。这时启动扇区的代码就会把控制权转移至0x500处。在第二个汇编文件中,代码会使用BIOS中断10h在屏幕上显示一个信息。C程序实现的功能则是把可执行的文件1拷贝至启动扇区,把可执行的文件2拷贝至软盘的第二扇区。


启动扇区代码


使用中断13h,启动扇区把软盘第二扇区里的内容加载至内存的0x5000处(段地址为0x500)。下面的代码是用于实现这一目的的代码,将其保存至文件sbect.s中。

LOC1=0x500
entry start
start:
mov ax,#LOC1
mov es,ax
mov bx,#0
mov dl,#0
mov dh,#0
mov ch,#0
mov cl,#2
mov al,#1
mov ah,#2
int 0x13
jmpi 0,#LOC1


上面代码第一行类似于一个宏。接下去的两行则是把值0x500加载至es寄存器中,这是软盘上第二扇区代码将拷贝到的地方(第一扇区是启动扇区)。这时,把段内的偏移设为0。

接下来把驱动器号送入dl寄存器中,其中磁头号送入dl寄存器中,磁道号送入ch寄存器中,扇区号送入cl寄存器中,扇区数送入al寄存器之中。我们想要实现的功能是把扇区2、磁道号为0、驱动器号为0的内容送至段地址0x500处。所有这些参数都和1.44MB的软盘相对应。

把2送入ah寄存器中,是选择了由中断13h提供的相应功能,即实现从软驱转移数据的功能。

最后调用中断13h,并且转至偏移为0的段地址0x500处。


第二个扇区的代码


第二个扇区中的代码如下所示(把这些代码保存至文件sbect2.s之中):

entry start
start:
mov ah,#0x03
xor bh,bh
int 0x10

mov cx,#26
mov bx,#0x0007
mov bp,#mymsg
mov ax,#0x1301
int 0x10

loop1: jmp loop1
mymsg:
.byte 13,10
.ascii “Operating System is Loading......”


上面代码将被加载至段地址为0x500处,并且被执行。在这段代码中,使用了中断10h来获取目前的光标位置,然后显示信息。

从第3行到第5行用于得到目前光标的位置,在此中断10h选用的是功能3。然后,清除了bh寄存器的内容,并把字符串送至ch寄存器中。在bx中,我们送入了页码及显示的属性。此处,我们想要在黑背景上显示白色的字符。然后,把要显示字符的地址送到bp之中,信息由两个字节组成,其值分别为13的10,它们分别对应回车和LF(换行)的ASCⅡ值。接下来是一个由29个字符组成的串;在下面实现的功能是输出字符串然后移动光标;最后是调用中断,然后进入循环。


C程序代码


C程序的源代码如下所示,将其存储为write.c文件。

#include <sys/types.h> /* unistd.h needs this */
#include <unistd.h> /* contains read/write */
#include <fcntl.h>
int main()
{
char boot_buf[512];
int floppy_desc, file_desc;
file_desc = open(“./bsect”, O_RDONLY);
read(file_desc, boot_buf, 510);
close(file_desc);
boot_buf[510] = 0x55;
boot_buf[511] = 0xaa;
floppy_desc = open(“/dev/fd0”, O_RDWR);
lseek(floppy_desc, 0, SEEK_SET);
write(floppy_desc, boot_buf, 512);
file_desc = open(“./sect2”, O_RDONLY);
read(file_desc, boot_buf, 512);
close(file_desc);
lseek(floppy_desc, 512, SEEK_SET);
write(floppy_desc, boot_buf, 512);
close(floppy_desc);
}


在上一期中,我曾经介绍过如何操作能启动的软盘。现在这一个过程稍微有点不同,首先把由bsect.s编译出来的可执行文件bsect拷贝至软盘的启动扇区。然后再把由sect2.s产生的可执行文件sect2拷贝至软盘的第二个扇区。

把上述文件置于同一目录之下,然后分别对其进行编译,方法如下所示:

as86 bsect.s -o bsect.o
ld86 -d bsect.o -o bsect


对sect2.s文件重复以上的操作,得出可执行文件sect2。编译write.c,插入软盘后执行write文件,命令如下所示:

cc write.c -o write
./write


下一步我们要做的事情


从软盘启动以后,可以看到显示出来的字符串。这是使用了BIOS中断来完成的。下一期要做的事情是在这个操作系统中实现实模式向保护模式的转换。

 


--------------------------------------------------------------------------------
htldm 回复于:2002-12-17 15:22:55
现在,这个操作系统已经越来越接近当年Linus Torvalds的那个具有“历史意义”的Linux内核了。因此,要马上把这个系统切换到保护模式之下。

什么是保护模式

自从1969年推出第一个微处理器以来,Intel处理器就在不断地更新换代,从8086、8088、80286,到80386、80486、奔腾、奔腾Ⅱ、奔腾4等,其体系结构也在不断变化。80386以后,提供了一些新的功能,弥补了8086的一些缺陷。这其中包括内存保护、多任务及使用640KB以上的内存等,并仍然保持和8086家族的兼容性。也就是说80386仍然具备了8086和80286的所有功能,但是在功能上有了很大的增强。早期的处理器是工作在实模式之下的,80286以后引入了保护模式,而在80386以后保护模式又进行了很大的改进。在80386中,保护模式为程序员提供了更好的保护,提供了更多的内存。事实上,保护模式的目的不是为了保护程序,而是要保护程序以外的所有程序(包括操作系统)。

简言之,保护模式是处理器的一种最自然的模式。在这种模式下,处理器的所有指令及体系结构的所有特色都是可用的,并且能够达到最高的性能。

保护模式和实模式

从表面上看,保护模式和实模式并没有太大的区别,二者都使用了内存段、中断和设备驱动来处理硬件,但二者有很多不同之处。我们知道,在实模式中内存被划分成段,每个段的大小为64KB,而这样的段地址可以用16位来表示。内存段的处理是通过和段寄存器相关联的内部机制来处理的,这些段寄存器(CS、DS、SS和ES)的内容形成了物理地址的一部分。具体来说,最终的物理地址是由16位的段地址和16位的段内偏移地址组成的。用公式表示为:

物理地址=左移4位的段地址+偏移地址。

在保护模式下,段是通过一系列被称之为“描述符表”的表所定义的。段寄存器存储的是指向这些表的指针。用于定义内存段的表有两种:全局描述符表(GDT)和局部描述符表(LDT)。GDT是一个段描述符数组,其中包含所有应用程序都可以使用的基本描述符。在实模式中,段长是固定的(为64KB),而在保护模式中,段长是可变的,其最大可达4GB。LDT也是段描述符的一个数组。与GDT不同,LDT是一个段,其中存放的是局部的、不需要全局共享的段描述符。每一个操作系统都必须定义一个GDT,而每一个正在运行的任务都会有一个相应的LDT。每一个描述符的长度是8个字节,格式如图3所示。当段寄存器被加载的时候,段基地址就会从相应的表入口获得。描述符的内容会被存储在一个程序员不可见的影像寄存器(shadow register)之中,以便下一次同一个段可以使用该信息而不用每次都到表中提取。物理地址由16位或者32位的偏移加上影像寄存器中的基址组成。实模式和保护模式的不同可以从图1和图2中很清楚地看出来。


图1 实模式的寻址


图2 保护模式下的寻址


图3 段描述俯的格式

此外,还有一个中断描述符表(IDT)。这些中断描述符会告诉处理器到那里可以找到中断处理程序。和实模式一样,每一个中断都有一个入口,但是这些入口的格式却完全不同。因为在切换到保护模式的过程中没有使用到IDT,所以在此就不多做介绍了。

进入保护模式

80386有4个32位控制寄存器,名字分别为CR0、CR1、CR2和CR3。CR1是保留在未来处理器中使用的,在80386中没有定义。CR0包含系统的控制标志,用于控制处理器的操作模式和状态。CR2和CR3是用于控制分页机制的。在此,我们关注的是CR0寄存器的PE位控制,它负责实模式和保护模式之间的切换。当PE=1时,说明处理器运行于保护模式之下,其采用的段机制和前面所述的相应内容对应。如果PE=0,那么处理器就工作在实模式之下。

切换到保护模式,实际就是把PE位置为1。为了把系统切换到保护模式,还要做一些其它的事情。程序必须要对系统的段寄存器和控制寄存器进行初始化。把PE位置1后,还要执行跳转指令。过程简述如下:

1.创建GDT表;

2.通过置PE位为1进入保护模式;

3.执行跳转以清除在实模式下读取的任何指令。

下面使用代码来实现这个切换过程。

需要的东西

◆ 一张空白软盘

◆ NASM编译器

下面是整个程序的源代码:

org 0x07c00; 起始地址是0000:7c00
jmp short begin_boot ; 跳过其它的数据,跳转到引导程序的开始处
bootmesg db "Our OS boot sector loading ......"
pm_mesg db "Switching to protected mode ...."
dw 512 ; 每一扇区的字节数
db 1 ; 每一簇的扇区数
dw 1 ; 保留的扇区号
db 2
dw 0x00e0
dw 0x0b40
db 0x0f0
dw 9
dw 18
dw 2 ; 读写扇区号
dw 0 ; 隐藏扇区号
print_mesg :
mov ah,0x13 ; 使用中断10h的功能13,在屏幕上写一个字符串
mov al,0x00 ; 决定调用函数后光标所处的位置
mov bx,0x0007 ; 设置显示属性
mov cx,0x20 ; 在此字符串长度为32
mov dx,0x0000 ; 光标的起始行和列
int 0x10 ; 调用BIOS的中断10h
ret ; 返回调用程序
get_key :
mov ah,0x00
int 0x16 ; Get_key使用中断16h的功能0,读取下一个字符
ret
clrscr :
mov ax,0x0600 ; 使用中断10h的功能6,实现卷屏,如果al=0则清屏
mov cx,0x0000 ; 清屏
mov dx,0x174f ; 卷屏至23,79
mov bh,0 ; 使用颜色0来填充
int 0x10 ; 调用10h中断
ret
begin_boot :
call clrscr ; 先清屏
mov bp,bootmesg ; 提供串地址
call print_mesg ; 输出信息
call get_key ; 等待用户按下任一键
bits 16
call clrscr ; 清屏
mov ax,0xb800 ; 使gs指向显示内存
mov gs,ax ; 在实模式下显示一个棕色的A
mov word [gs:0],0x641 ; 显示
call get_key ; 调用Get_key等待用户按下任一键
mov bp,pm_mesg ; 设置串指针
call print_mesg ; 调用print_mesg子程序
call get_key ; 等待按键
call clrscr ; 清屏
cli ; 关中断
lgdt[gdtr] ; 加载GDT
mov eax,cr0
or al,0x01 ; 设置保护模式位
mov cr0,eax ; 将更改后的字送至控制寄存器中
jmp codesel:go_pm
bits 32
go_pm :
mov ax,datasel
mov ds,ax ; 初始化ds和es,使其指向数据段
mov es,ax
mov ax,videosel ; 初始化gs,使其指向显示内存
mov gs,ax
mov word [gs:0],0x741 ; 在保护模式下显示一个白色的字符A
spin : jmp spin ; 循环
bits 16
gdtr :
dw gdt_end-gdt-1 ; gdt的长度
dd gdt ; gdt的物理地址
gdt
nullsel equ $-gdt ; $指向当前位置,所以nullsel = 0h
gdt0 ; 空描述符
dd 0
dd 0 ; 所有的段描述符都是64位的
codesel equ $-gdt ; 这是8h也就是gdt的第二个描述符
code_gdt
dw 0x0ffff ; 段描述符的界限是4Gb
dw 0x0000
db 0x00
db 0x09a
db 0x0cf
db 0x00
datasel equ $-gdt
data_gdt
dw 0x0ffff
dw 0x0000
db 0x00
db 0x092
db 0x0cf
db 0x00
videosel equ $-gdt
dw 3999
dw 0x8000 ; 基址是0xb8000
db 0x0b
db 0x92
db 0x00
db 0x00
gdt_end
times 510-($-$$) db 0
dw 0x0aa55


把上面的代码存在一个名为abc.asm的文件之中,使用命令nasm abc.asm,将得出一个名为abc的文件。然后插入软盘,输入命令:dd if=abc of=/dev/fd0。该命令将把文件abc写入到软盘的第一扇区之中。然后重新启动系统,就会看到如下的信息:

*Our os booting................
* A (棕色)
* Switching to protected mode....
* A (白色)


对代码的解释

上面给出了所有的代码,下面我对上述代码做一些解释。

◆ 使用的函数

下面是代码中一些函数的说明:

print_mesg 该子程序使用了BIOS中断10h的功能13h,即向屏幕写一字符串。属性控制是通过向一些寄存器中送入不同的值来实现的。中断10h是用于各种字符串操作,我们把子功能号13h送到ah中,用于指明要打印一个字符串。al寄存器中的0说明了光标返回的起始位置,0表示调用函数后光标返回到下一行的行首。如果al为1则表示光标位于最后一个字符处。

显存被分成了几页,在同一时刻只能显示其中的一页。bh指明的是页号;bl则指明要显示字符的颜色;cx指明要显示字符串的长度;dx指明光标的位置(即起始的行和列)。所有相关寄存器初始化完成以后,就可以调用BIOS中断10h了。

get_key 使用中断16h的子功能00h,从屏幕得到下一个字符。

clrscr 该函数使用了中断10h的另外一个子功能06h,用于输出开始前清屏。初始化时给al中送入0。寄存器cx和dx指明要清屏的屏幕范围,在本例中是整个屏幕。寄存器bh指明屏幕填充的颜色,在本例中是黑色。

◆ 其它内容

程序一开始是一条短跳转指令,跳到begin_boot处。在实模式下,在此打印一个棕色的“A”,并且设置一个GDT。切换到保护模式,并且打印一个白色的“A”。这两种模式使用的都是自己的寻址方法。

在实模式下,使用段寄存器gs指示显存位置,我们使用的是CGA显卡(默认基址是0xb8000)。在代码中是不是漏了一个0呢?没有,因为实模式下会提供一个附加的0。这种方式也被80386继承下来了。A的ASCⅡ是0x41,0x06指明了需要一个棕色的字符。该显示会一直持续直至按下任意键。下面要在屏幕上显示一句话,告诉使用者下面马上要进入保护模式了。

启动到保护模式,在进行切换时不希望此时有中断的影响,故要关闭所有的中断(使用cli来实现)。然后对GDT初始化。在整个切换过程中,对4个描述符进行了初始化。这些描述符对代码段(code_gdt)、数据和堆栈段(data_gdt),以及为了访问显存而对显示段进行初始化。此外,还会对一个空描述符进行初始化。

GDT的基址要加载至GDTR系统寄存器之中。gdtr段的第一个字加载的是GDT的大小,在下一个双字中则加载的是基址。然后,lgdt指令把把gdt段加载至GDTR寄存器中。现在已经做好了切换到保护模式前的所有准备。最后一件事情就是把CR0寄存器的PE位置1。不过,即使这样还没有处于保护模式状态之下。

设置了PE位以后,还需要通过执行JMP指令来清除处理器指令预取队列。在80386中,使用指令前总是先将其从内存中取出,并且进行解码和寻址。然而,当进入保护模式以后,预取指令信息(它还处于实地址模式)就无效了。使用JMP指令的目的就是强迫处理器放弃无效的信息。

现在,已经在保护模式下了。那么,如何检测是在保护模式状态之下呢?让我们来看一看屏幕上这个白色的字母A。在这里,使用了数据段选择符(datase1)对数据段和附加段进行了初始化,使用显示段选择符(videose1)对gs进行了初始化。告示的字符“A”其ASCⅡ值和属性位于[gs:0000]处,也就是b8000:0000处。循环语句使得该字符一直在屏幕上显示,直至重新启动系统。

下一步要做的事

现在,这个操作系统已经工作在保护模式下了,但是实际上它并不实现什么具体的功能。你可以在这个基础上为它增加各种操作系统所具有的功能。我们自己动手写操作系统到此也就告一段落。

posted @ 2007-01-23 13:07 高山流水 阅读(294) | 评论 (0)编辑 收藏

猎人和猎狗的故事
一、目标
  一条猎狗将兔子赶出了窝,一直追赶它,追了很久仍没有捉到。
  牧羊看到此种情景,讥笑猎狗说:“你们两个之间小的反而跑得快得多。”
  猎狗回答说:“你不知道我们两个跑的目的是完全不同的 !我仅仅为了一顿饭而跑,他却是为了性命而跑呀!”

二、动力

  这话被猎人听到了,猎人想:猎狗说的对啊,那我要想得到更多的猎物,得想个好法子。
  于是,猎人又买来几条猎狗,凡是能够在打猎中捉到兔子的,就可以得到几根骨头,捉不到的就没有饭吃。这一招果然有用,猎狗们纷纷去努力追兔子,因为谁都不愿意看着别人有骨头吃,自己没的吃。就这样过了一段时间,问题又出现了。大兔子非常难捉到,小兔子好捉。但捉到大兔子得到的奖赏和捉到小兔子得到的骨头差不多,猎狗们善于观察,发现了这个窍门,专门去捉小兔子。慢慢地,大家都发现了这个窍门。猎人对猎狗说最近你们捉的兔子越来越小了,为什么猎狗们说反正没有什么大的区别,为什么费那么大的劲去捉那些大的呢?

三、长期的骨头

  猎人经过思考后,决定不将分得骨头的数量与是否捉到兔子挂钩,而是采用每过一段时间,就统计一次猎狗捉到兔子的总重量的方法。按照重量来评价猎狗,决定其在一段时间内的待遇。
  于是猎狗们捉到兔子的数量和重量都增加了。
  猎人很开心。但是过了一段时间,猎人发现,猎狗们捉兔子的数量又少了,而且越有经验的猎狗,捉兔子的数量下降的就越利害。于是猎人又去问猎狗。
  猎狗说:“我们把最好的时间都奉献给了您,主人,但是我们随着时间地推移会变老,当我们捉不到兔子的时候,您还会给我们骨头吃吗?”

四、骨头与肉兼而有之

  猎人做了论功行赏的决定。分析与汇总了所有猎狗捉到兔子的数量与重量,规定如果捉到的兔子超过了一定的数量后,即使捉不到兔子,每顿饭也可以得到一定数量的骨头。猎狗们都很高兴,大家都努力去达到猎人规定的数量。一段时间过后,终于有一些猎狗达到了猎人规定的数量。这时,其中有一只猎狗说:“我们这么努力,只得到几根骨头,而我们捉的猎物远远超过了这几根骨头,我们为什么不能给自己捉兔子呢”于是,有些猎狗离开了猎人,自己捉兔子去了。
五 有权分享猎人意识到猎狗正在流失,并且那些流失的猎狗像野狗一般和自己的猎狗抢兔子。情况变得越来越糟,猎人不得已引诱了一条野狗,问他到底野狗比猎狗强在那里。野狗说:“猎狗吃的是骨头,吐出来的是肉啊!”接着又道:“也不是所有的野狗都顿顿有肉吃,大部分最后骨头都没的舔!不然也不至于被你诱惑。”于是猎人进行了改革,使得每条猎狗除基本骨头外,可获得其所猎兔肉总量的n%,而且随着服务时间加长,贡献变大,该比例还可递增,并有权分享猎人总兔肉的m%。就这样,猎狗们与猎人一起努力,将野狗们逼得叫苦连天,纷纷强烈要求重归猎狗队伍。

  故事还在继续

  只有永远的利益,没有永远的朋友

  日子一天一天地过去,冬天到了,兔子越来越少,猎人们的收成也一天不如一天。而那些服务时间长的老猎狗们老得不能捉到兔子,但仍然在无忧无虑地享受着那些他们自以为是应得的大份食物。终于有一天猎人再也不能忍受,把它们扫地出门,因为猎人更需要身强力壮的猎狗……

  Birth of Micro Bone Co.

  被扫地出门的老猎狗们得到了一笔不菲的赔偿金,于是他们成立了Micro Bone公司。他们采用连锁加盟的方式招募野狗,向野狗们传授猎兔的技巧,他们从猎得的兔子中抽取一部分作为管理费。当赔偿金几乎全部用于广告后,他们终于有了足够多的野狗加盟。公司开始赢利。一年后,他们收购了猎人的家当。

  Development of Micro Bone Co.

  Micro Bone公司许诺给加盟的野狗能得到公司n%的股份。这实在是太有诱惑力了。这些自认为是怀才不遇的野狗们都以为找到了知音:终于做公司的主人了,不用再忍受猎人们呼来唤去的不快,不用再为捉到足够多的兔子而累死累活,也不用眼巴巴地乞求猎人多给两根骨头而扮得楚楚可怜。这一切对这些野狗来说,比多吃两根骨头更加受用。于是野狗们拖家带口地加入了Micro Bone,一些在猎人门下的年轻猎狗也开始蠢蠢欲动,甚至很多自以为聪明实际愚蠢的猎人也想加入。好多同类型的公司像雨后春笋般地成立了,Bone Ease,Bone.com,China Bone……一时间,森林里热闹起来。明星的诞生猎人凭借出售公司的钱走上了老猎狗走过的路,最后千辛万苦地要与Micro Bone公司谈判的时候,老猎狗出人意料地答应了猎人,把Micro Bone公司卖给了他。老猎狗们从此不再经营公司,转而开始写自传《老猎狗的一生》,又写:《如何成为出色的猎狗》、《如何从一只普通猎狗成为一只管理层的猎狗》、《猎狗成功秘诀》、《成功猎狗500条》、《穷猎狗,富猎狗》,并将老猎狗的故事搬上屏幕,取名《猎狗花园》,3只老猎狗成了家喻户晓的明星。收版权费,没有风险,利润更高。

ps:干活的总是拿得少的,拿得多的都是不干活的。

posted @ 2007-01-23 13:05 高山流水 阅读(320) | 评论 (0)编辑 收藏

 

影响力管理语录 
来源:上海影响力--培训中心

1、每一分每一秒做最有生命力的事情.
2、一日之计在于昨夜.
3、一开始就要冲刺.
4、一次性就将事情做对.
5、做对的事情,而不仅仅把事情做好.
6、客户就是裁判.
7、我们不用语言教学,我们用心灵撞击心灵.
8、先处理心情,再处理事情.
9、立场要坚定、态度要热情.
10、节约一块钱,比赚一块钱很容易.

11、成功一定有方法,失败一定有原因.
12、思路决定出路.
13、持续改善.
14、无限接近零缺陷.
15、希望别人怎样对待自己,就怎么对待别人.
16、完成本职工作,就是对队友最大的支持.
17、坚持到底,永不放弃.
18、简单的工作练到极致,就是绝招.
19、说到听者想听,听到说者想说.
20、高明的领导者领导员工的思维. 不高明的领导者看管员工的行为.

21、培训很贵,不培训更贵.
22、人是企业竞争致胜的第一资本.
23、学习是企业第二生产力.
24、学习是最赚钱的投资.
25、小公司做事,大公司“做”人.
26、行动力来源:追求快乐,逃离痛苦.
27、事物本身并不影响人.人们只受对事物看法的影响.
28、不是失败,只是暂没有成功.
29、命运在自己的手里,而不是在别人的嘴里.
30、我一定要,我就一定能.

31、爱是一切动力的源泉.
32、自由的代价是自律.
33、自信不一定成功,但不自信铁定离成功更远.
34、目标决定现实,而不是现实决定目标.
35、“为何”比“如何”更重要.
36、大目标是小目标的结果,小目标是大目标的条件.
37、修订计划,而不是改变目标.
38、成功者的第一反应:找方法,而不是找借口.
39、所有的限制,一开始均来源于自我设限.
40、人与人之间的差别,一开始在于思考问题的方式不同.

41、21天改变命运.
42、我们不改变坏习惯,坏习惯将控制我们一生.
43、将练习当成比赛.
44、将汗水流在练习场上,而不要将泪水流在竞技场上.
45、比裁判更加严格的要求你的队员.
46、你越努力,你的运气越好.
47、跟什么人在一起,就将成为什么人.
48、只要不服输,失败就不会是定局.
49、目标就是你未来的现实.
50、成功就是简单的事情重复去做.

51、成功是因为态度.
52、我是我认为的我.
53、我是一切的根源.
54、不是不可能.
55、山不过来我就过去.
56、每天进步一点点.
57、决心决定成功.
58、天助自助者.
59、太棒了.
60、成功的捷径就是按最有效的成功策略行施,用错方法就是走弯路.

posted @ 2006-10-26 09:36 高山流水 阅读(210) | 评论 (0)编辑 收藏

   本文起由乃是见到有些青年居然认为中国没有哲学,哲学只有西方有。先说"哲学" 一词的意义。 "哲学" 一词英文為philosophy, 它源于希腊文,语根為philo 及sophia, 原义為爱智慧(love of wisdom), 或即对智慧的追求(strivefor wisdom)。 "智慧" 一词意义十分广泛, 用现代的说话來说, 它泛指一切人类理性(reason)的思考和反省活动。罗素把它总结为:哲学是关于真理的学问。现在中国官方的定义最科学就是:哲学是世界观,哲学是方法论。

  世界观和方法论中国早已有之,这里不用赘述。因此中国没有哲学是荒谬之说。可为什么中国没有现在西方哲学这样的模式呢?这说来话长,要慢慢讲。先说西方哲学主要是来源于希腊的数学和几何的逻辑思维,并机械的认为像数学和几何一样从已知的知识可以推出未知的结论。大家知道要进行逻辑思维首先要进行定义,可是定义往往难以精确,推理的过程也经常的与事实不符。这就是西方哲学的困境。因此英国哲学家罗素在他的《哲学问题》结尾这样说道:“哲学之所以应该学习并不在于它能对于所提出的问题提供任何确定的答案,因为通常不可能知道有什么确定的答案是真确的,而是在于这写问题的本身;原因是,这写问题可以扩充我们对于一切可能事物的概念,丰富我们心灵方面的想象力,并减低教条式的自信,这些都可能禁锢心灵的思考作用。”在这段话里罗素明白无误的告诉我们,西方哲学家要求精确定义的哲学是根本精确不了的。

  再来看几个实例:2+2=4这是哲学罗素经常举例的例子,这应该是毫无疑问的真理。可是不耐推究,两个苹果加两个苹果就是四个苹果。可是两个人加两个人就不一定是四个人,这里还需要时间或其他的条件加以限制等式才能成立,要不然就会出现两个人加两个人生多少个人的问题;还会出现人与人争斗仇杀减少人数的问题。因此看上去明白无误的真理却不是真理。还有我们平常经常有的概念:明天太阳会再出现。可是也不是真理,因为在南极或在北极都有可能出现明天看不见太阳的情况,因此也不是真理。还有一天24小时是固有的概念,可是这样大家认为精确的概念也是不精确的,因为地球自转的加快每天还有零点零几秒的误差,因此也不能有精确的概念。例子还有很多,这就是西方哲学的困境。也是西方哲学流派繁多却难以统一的原因,因为他们超越不了找不到本质。

  定义不能精确,推理就不能精确,也因此难以有精确的定论。这些中国人的祖先早以了然于胸,因此“道可道,非常道。名可名,非常名”老子在《道德经》就出现了这样的理念。说明规律与实质性的真理是难以精确说出的。应该说中国的古代哲学比西方的哲学还高一个层次。中国哲学要求讲出来的是一个共性,也就是上个世纪西方大哲学家罗素等才朦胧意识到的什么“共相”。

  再有西方哲学的思维律是:同一律---“是就是是”;矛盾律---“任何东西不能即是有不是”;排中律---“任何东西必须或者是或者不是”。这是西方哲学归纳推理和演绎推理的根据。这样就产生了种种的对立矛盾,也产生了很多的对立概念。如:朋友—敌人、和平—战争、对与错、……。由此西方人的思维容易走极端,完全忽视了事物发展的中间环节。大家都知道人与人的关系出了敌人、朋友还有非敌非友。而中国古人的哲学概念早已脱离对立的概念,儒家的基本点就是“中庸”。由于中国的文化是从周易演化而来,因此大家早明白物极必反的道理,凡事取‘中庸’用其不满不溢之意。

  总的来讲,中国古代的哲学已经经过了现在西方哲学的思辨期,早以摆脱了现在西方哲学的学术困境。中国古代哲学只给出事物的框架或性质,接着就是由读者自己去理解、思考。如对待一个木做的方桌子,中国哲学的描述就是木的、长方形的,这样就算完成了对桌子描述。而像黑格尔、罗素、康德、...等西方哲学家,如果描述一张桌子,为了极力精确要从观察着角度考虑,要从光线变化考虑等等,因此难以对桌子有精确的描述。也就是说中国古人跳过了现代西方哲学的困惑,进行了抓住本质的描述。

  由于中国古代哲学的特点也就形成了中国文化的特点,中国的字画就是比西方油画高一等级的艺术。西方油画在于写实的反映,只有到了现代才有了什么抽象派、野兽派等不是写实的画法。而中国画的留白,又是另一境界,他写出的意境与观赏者的感觉是对应的,是白云就是云;是青草的留白也能看出是青草;是山峦也能看出是山峦;这是一个印象,中国画家把这些印象做为留白画下来,观画者自然明白。中国画的精义就是“神似”,完全是一种抽象的艺术。也就是我们所说的认识第二阶段的理性认识,它超越了第一阶段的感性认识。中国的哲学不拘泥于精确的定义,而只要求对事物本质的描

  述和讲明道理。听者或读者是否能明白要看读者自己修养的水平,能明白“知天命”则是自己的造化。这里的‘天命’乃是事物的发展规律与迷信无关。不能明白哲理乃是修养不够是自己的损失。中国哲学影响生活的还有语言,语言也是照这样的思维模式进行。文言文能明白就明白,是‘仁者见仁,智者见智。’。难怪乎连朱熹这样的大学士也只能说大学的释语才准确,而他自己对其他的解释可能产生歧义。想必行文至此已没有人再说中国没有哲学了吧。

  “三十辐共一毂,当其无,有车之用。埏埴以为器,当其无,有器之用。凿户牖以为室,当其无,有室之用。故有之以为利,无之以为用。”《道德经》十一章说明的正是大哲学家罗素他们搞不明白的2+2=4的问题。当两千多年前的老子说明‘有’消失于‘无’时,西方哲学家们还在讨论2+2=4的逻辑是否真实的问题。

  由于中国哲学的进步,也就是世界观的进步,中国人早就没有什么“神”的概念。中国文化中的‘天命’、‘道’实际上就是事物的发展规律。《论语·述而》里“子不语怪力乱神”。就是儒家不信神鬼的最有力证明。而西方哲学在十七世纪以前还是以教会学派为主的哲学。以后才有脱离以‘神论’为中心的唯物学派,唯物论才得以慢慢慢慢推行。虽然早在希腊时期就有关于原子论的论述,可这样的世界观在以基督教为主的社会里是没有市场的,也是不占主导地位的。因此从思想层次方面来讲中国的哲学也要比西方的哲学高一个层次。

posted @ 2006-10-18 17:21 高山流水 阅读(239) | 评论 (1)编辑 收藏

 

  No.1 最值得推荐的是  The Mystery of time and space
      http://www.albartus.com/motas/
    故事连续性很强,有12个房间,并且还在不断推出中,是世界各地玩家最爱。同时该游戏作者即是很大牌的以制作逃脱游戏出名的Logan,在罗根自己的网页里也搜集了绝大多数世界上有名的逃脱游戏网址,在这个“神秘时间和空间”的游戏里面有紧张气氛和alient,还有基因技术航空什么的一堆高科技玩意。玩这个游戏,不仅仅需要乱抓一把的运气,很多关卡必须要你去解题和运用手中工具解决问题。玩家最称称乐道的是他们每次玩出游戏后在名人堂聚会顺便表明一下自己的国家城市,好似攀比哪里人最聪明一样。此外,这个游戏可以在线与世界玩家讨论,系统也会提示你过关诀窍。
  
  NO 2 深红色房间和碧绿色房间(居然是日本公司开发,我吐)
  这个游戏堪称鬼屋经典,在第二个房间里营造的恐怖气氛相当不错,需要一点道行和运气,适合鬼友自娱。不过情节稍嫌仓促粗糙,毕竟没有后续故事推动发展。
    第一个房间http://www.lancs.ac.uk/ug/gaoq2/fun/escape.htm
    第二个房间http://www.fasco-cs.com/works/viridian/index_e.html
    
    No 3 走入房间(留守)
   难得一见的照片实景游戏,这次是要走到一个北美大屋子里去,本游戏制作当然不错,可惜就笔者水平来讲,不懂很多的电器知识就很难。而且游戏大量的真实场景让人有点眼花缭乱。这个游戏一定要看攻略才能玩过,但还是推荐。
  
  No 4 埃及魔宫The MisteryMaster
  http://home.hccnet.nl/p.c.de.jong/
    这个一开始就是骷髅一堆,进门都不容易,进入以后,会发现,和其他游戏不同在于,此游戏的技巧居然是是是玩家要懂得怎么用搜索引擎google。游戏中涉及很多古代魔神和恐怖的魔灵代表。例如19世纪最有名的连环杀人犯的名字等等,每一题的解答需要玩家自己用心的搜索,也同时增长了很多另类知识。游戏其实分为两个部分,如果第一部分是深入魔宫地狱的话,第二部分就是寻找天堂所在了。游戏的宗教成分相当强。
    
    No 5 寻找真爱 truelove
  http://www.truelove.gr/
  此游戏虽然是某个巧克力公司推出的宣传作品,但制作相当精良,游戏情节也很连贯,而游戏贯入了类似神偷的技巧,也是很引人的因素。游戏中可以选择男女角色,也可以选择你和你真爱的名字,然后某天早晨醒来,你突然发现自己的爱人不见了,唯一的线索只是一张巧克力包装纸上的寥寥数字而已。于是你打理背包,走上遥远至埃及的征途,当然,首先你第一步要做的是怎么从你那公寓里面出去而已。这个游戏可以有朋友相助参与,但必须朋友在线,如果大家不能保证一起上线,一定要选择自己alone,否则会出不了公寓大门。游戏也有两个part。
    
  No 6 清朝小猫咪
   http://www.radio-canada.ca/jeunesse/sagwa/quetes/index.swf
   推荐它是因为这个游戏完全中国风体现,古典而精致,游戏中主角和清朝人物的造型相当有趣可爱。但是这是加拿大推出的一个法语游戏,理解性稍差,不过游戏还算趣味较可。
  
  
  No 7 Chasm
  http://www.abc.net.au/gameon/chasm/chasmgame.htm
  推荐这个纯粹是我个人爱好,Chasm是我很喜欢的一个小游戏,音乐很优美,故事很感人,一个小小的家伙背负着整个山谷的使命,要去修巨大的水管工程,这个不是逃脱游戏来的,属于冒险类,要用逻辑和常识思考,而不是到处乱抓就可以了事.
    而这个网站上有真实图片的提供,因为是真实故事和那个山谷改编的,所以感人啊,看那个好深的山谷里凭空架起的水渠,真是伟大的工程哦.
  
  No 8 日本制作的尸人flash
  http://www.forbidden-siren.com/
  我没有玩完,感觉是很恐怖的,比骷髅房间还恐怖些
  
  leo历险记
  http://www.et-express.com/flashgame/minigame/mind017.swf
  这是国外制作的类似于神秘时空的游戏,
  
  寻找厕所
  http://mail.im.tku.edu.tw/~coolray/RayRoomGame.swf
  
  拯救小外星人milkiw
  http://www.marleentimmer.com/worteldrie/milkiw/english/game.html
  
  拯救人质(阴暗的小房间)
  http://www.higopage.com/droom/index.html
  
  
  操纵在手的骷髅
  http://bbs.popv.net/UploadFile/200332313415983689.swf
  做的很好玩的flash,推荐
  
  
  以下是一些其他的冒险和鬼屋逃脱游戏
  米勒山庄疑案(古堡疑云)
  http://www.xinqing.sjtu.edu.cn/dongman/MyWeb/%C3%D7%C0%D5%C9%BD%D7%AF%D2%C9%B0%B8temp1.htm
  以前国内好像很流行过Flash制作的一个什么米勒山庄,加上续集一共12个地址,那个很恐怖,游戏情节还很不错,但因为有时间限制,经常让人死翘翘,而游戏由于不是链接制作,每一关必须重新打开另外一个网址才可,相对而言,似乎你不想玩的那关就可以跳过,甚至直接跳到最后一关看剧情也可。所以我认为游戏娱乐性欠缺。
  
  丛林冒险系列(台湾翻译X档案,共6季,每季4集)
  http://www2.warnerbros.com/steppenwolf/med/episode1.swf
  还有一个丛林冒险系列,和米勒山庄一样是要每个地址分别打开的,故事情节也很强,但要用键盘和enter键走来走去,快把人累死了。
  
  梦游先生
  http://www.snoozleberg.com/
  梦游先生系列有点港托托的,人物有很多命,网上有攻略,导致我玩的时候没有什么兴致。
  
  适合女孩子的温馨小游戏数则,很感人优美
  http://www.ferryhalim.com/orisinal/
  
  
  各种鬼屋游戏
  这些鬼屋游戏其实一点也不恐怖啦,纯粹看反应,也没有太多技巧
  
  精灵卡士伯鬼屋
  http://www.cyberteens.com/fg/sarbakan/casper/Casper.swf
  
  加菲猫鬼屋
  http://www.perfectionpastries.com/sshII/ssh2main.swf
  
  史酷毙狗鬼屋
  http://www.cartoonnetwork.com/play/adventure/scooby_creepycastle/game.swf?trackerPath=tracker.swf&sw1=/play/tools/img/billboards/ros.swf&sw2=5
  
  http://promo.warnerbros.com/sd_brand/med/highSeas/Scooby1Final.swf

posted @ 2006-10-18 17:06 高山流水 阅读(415) | 评论 (0)编辑 收藏

嵌入式软件测试的困难之一就是如何获取测试产生的数据, 大多数的软件测试工具在测试软件的时候都要提供测试脚本,如果进行覆盖率分析就要对代码插装, 测试可执行程序在目标环境下运行时就会有数据产生,这些数据就是产生测试报告的重要输入条件, 所以要顺利实现嵌入式软件测试, 首先需要解决的就是如何把测试数据上载会主机.
经过我们实际摸索发现, 大概我们可以把数据的上载分为3 种方式:
1. 实际的物理通道
2. 开发工具IDE的虚拟IO功能
3. 读取内存区数据
下面我们对这几种方式做一些简单的介绍:
实际的物理通道
这种方式就是目标机和主机之间具备物理的通信方式, 比如以太网, 串口,并口, USB等, 这几种方式, 在测试的时候我们可以直接使用这种通信程序, 和主机通信, 实现测试数据上载, 一般情况下,测试工具的库中IO函数使用fprintf(), 那么在这种方式下,就需要修改测试工具的库, 假设以太网的发数据的函数是Netsend(), 那么我们需要定制fprintf, 使它调用Netsend(), 这样就可以实现数据上传了. 这种方式最方便但是要求系统必须已经具备这种通信方式和通信软件, 一般适用于系统级的测试.
开发工具虚拟IO
开发嵌入式软件一般需要支持交叉开发方式的开发工具, 大多数这种开发工具具备编译,下载,调试的功能, 测试时也可以借助开发工具来下载测试程序, 需要注意的是, 有些高级的开发工具IDE, 具备虚拟IO功能, 给测试带来了很大的方便, 比如说: Tornado, TI CCS,
在Tornado的shell中运行测试程序时, 可以把printf的内容打印到消息窗口中, CCS可以支持fprintf,直接在主机上生成测试数据文件, 用户在使用这些工具的时候, 就像在主机上测试一样, 完全可以理由开发工具赋予的模拟IO功能.
读取内存数据
假设目标系统既没有物理通信方式, 开发工具也没有虚拟IO功能, 我们还可以采用读取内存数据的方式, 我们可以开辟一块足够大的缓存, 修改测试工具的库, 把输出的数据写入buffer中, 在测试过程中或者测试执行后, 使用开发工具读取内存的功能把缓存中的数据读取出来,在主机上保存成文件,这种方式需要系统有足够的内存资源, 但是适用性很广,因为几乎所有的开发调试工具都具备这样的功能.
总之嵌入式软件测试很复杂, 需要根据实际情况采取不同的策略. 本文只是单独就数据读取的问题做了一些讨论.

posted @ 2006-07-24 11:34 高山流水 阅读(322) | 评论 (0)编辑 收藏

1、 从测试功能上分
(1) 单元测试
针对不同语言,如JUNIT
(2) 功级测试
E—Test:功能强大,由于不是采用POST URL的方式回放脚本,所以可以支持多内码的测试数据(当然要程序支持),基本上可以应付大部分的WEB SITE。
MI公司的WINRUNNER
COMPUWARE的QARUN
RATIONAL的SQA ROBOT
(3) 压力测试
MI公司的WINLOAD
COMPUWARE的QALOAD
RATIONAL的SQA LOAD
(4) 负载测试
LOADRUNNER
RATIONAL VISUAL QUANTIFY
(5) WEB测试工具
MI公司的ASTRA系列
RSW公司的E—TEST SUITE等
(6) WEB系统测试工具
WORKBENCH
WEB APPLICATION STRESS TOOL(WAS)
(7) 数据库测试工具
TESTBYTES
(8) 回归测试工具
RATIONAL TEAM TEST
WINRUNNER
(9) 嵌入式测试工具
ATTOLTESTWARE。是ATTOLTESTWARE公司的自动生成测试代码的软件测试工具,特别适用于嵌入式实时应用软件单元和通信系统测试。
CODETEST是AppliedMicrosystemsCorp.公司的产品,是广泛应用的嵌入式软件在线测试工具
GammaRay。GammaRay系列产品主要包括软件逻辑分析仪GammaProfiler、可靠性评测工具GammaRET等。
LogiScope是TeleLogic公司的工具套件,用于代码分析、软件测试、覆盖测试。
LynxInsure++是LynxREAL-TIMESYSTEMS公司的产品,基于LynxOS的应用代码检测与分析测试工具
MessageMaster是ElviorLtd.公司的产品,测试嵌入式软件系统工具,向环境提供基于消息的接口。
VectorCast是VectorSoftware.Inc公司的产品。由6个集成的部件组成,自动生成测试代码,为主机和嵌入式环境构造可执行的测试架构。
(10) 系统性能测试工具
Rational Performance
(11) 页面链接测试
Link Sleuth
(12) 测试流程管理工具
Test Plan Control
(13) 测试管理工具
TestDirector
Rational公司的Test Manager
Compuware公司的QADirector
TestExpert:是Silicon Valley Networks公司产品的测试管理工具,能管理整个测试过程,从测试计划、测试例程、测试执行到测试报告。
(14) 缺陷跟踪工具
TrackRecord等
(15) 其他测试工具
TestVectorGenerationSystem是T—VECTechnologies公司的产品。提供自动模型分析、测试生成、测试覆盖分析和测试执行的完整工具包,具有方便的用户接口和完备的文档支持。
TestQuestPro是TestQuest公司的非插入码式的自动操纵测试工具,提供一种高效的自动检测目标系统,获取其输出性能的测试方法。
TestWorks是SoftwareResearch.Inc公司的一整套软件测试工具,既可单独使用,也可捆绑销售使用。
2、 从测试的方法上分:
(1) 白盒测试工具
白盒测试工主要有:Numega、PuRe、软件纠错工具(Rational Purify)。
内存资源泄漏检查:
Numega中的BounceChecher
Rational的 Purify等
代码覆盖率检查:
Numega的TrueCoverage
Rational的PureCoverage
TeleLogic公司的LogiScope
Macabe公司的Macabe
代码性能检查:
Numega的TrueTime
Rational的Quantify等
代码静态度量分析度量检查工具:LogiScope和Macabe等
黑盒测试工具主要有:QACenter、SQATeamTest、Rational Visual Visual Test。
QACenter:QACenter帮助所有测试人员创建一个快速、可重用的测试过程。这些测试工具自动帮助管理测试过程、快速分析和调试程序,包括针对回归、强度、单元、并发、集成、移植,容量和负载建立测试用例,自动执行测试和产生文档结果。QACenter主要包括以下几个模块:
QARun:应用的功能测试工具
QALoad:强负载下应用的性能测试工具
QADirector:测试的组织设计和创建以及管理工具。
TrackRecord:集成的缺陷跟踪管理工具。
EcoTools:高层次的性能监测工具。


3、部分具体测试工具的介绍
(1)、性能优化工具EcoScope
EcoScope 是一套定位于应用(即服务提供者本身)及其所依赖的所有网络计算资源的解决方案。EcoScope可以提供应用视图,并标出应用是如何与基础架构相关联的。这种视图是其他网络管理工具所不能提供的。EcoScope能解决在大型企业复杂环境下分析与测量应用性能的难题。通过提供应用的性能级别及其支撑架构的信息,EcoScope能帮助IT部门就如何提高应用性能提出多方面的决策方案。
EcoScope的应用主要表现在以下几个方面:
确保成功部署新应用
维护性能的服务水平
加速问题检测与纠正的高级功能
定制视图有助于高效地分析数据
(2)、数据库测试数据自动生成工具——TestBytes
在数据库开发的过程中,为了测试应用程序对数据库的访问,应当在数据库中生成测试用例数据,我们可能会发现当数据库中只有少量数据时,程序可能没有问题,但是当真正投入到运用中产生了大量数据时就出现问题了,这往往是因为程序的编写没有达到,所以一定及早地通过在数据库中生成大量数据来帮助开发人员完善这部分功能和性能。
TestBytes是一个用于自动生成测试数据的强大易用的工具,通过简单的点击式操作,就可以确定需要生成的数据类型(包括特殊字符的定制),并通过与数据库的连接来自动生成数百万行正确的测试数据,可以极大地提高数据库开发人员、QA测试人员、数据仓库开发人员、应用开发人员的工作效率。
(3)、PC—LINT
PC—LINT 主要进行更严格的语法检查功能,还完成相当程度的语义检查功能。可以这样认为:PC—LINT是一个更加智能、更加严格的编译器。PC—LINT在实现语法和某些语义规则检查时,是通过参数配置完成的,它的选项就有数百个之多,因此,在使用PC—LINT过程中,了解选项的含义也很重要。
(4)、TCL
TCL是Tool Command Language的缩写,它是一种很流行的脚本解释器,尤其在测试领域,它的最大特点是可移植性好,接口简单,方便,可以很容易地嵌入到软件中,作为自己的解释器使用。
TCL提供两种接口:编程接口和用户接口。编程接口是通过LIB或DLL形式提供的,提供了一些函数(命令)供调用,包括:分配一个解释器指针(对象);初始化解释器(指针);注册扩展函数等。用户接口很简单,即编写的脚本,脚本里面包含对扩展命令的调用。
(5)VB测试工具:VB Watch
(6)Java 程序的测试工具
1)Bean—Test
2)EJBQuickTest
3)JStyle
4)JTest
5)HttpUnit
6)JUnit
(7)、覆盖测试
C—Cover
C—Cover是一个测试工具软件,用来找出没有被测到的代码,并报告测试的覆盖率。C—Cover
只支持C/C++的代码覆盖率分析,其它语言不支持。但不受OS的限制。
===============================================
单元测试方面:(对开发人员比较有用) J-Unit工具。
  功能测试方面:E-test是个不错的选择,功能很强大,由于不是采用Post URL的方式回放脚本,所以可以支持多内码的测试数据(当然要程序支持)。基本上可以应付大部分的Web Site。
  如果只是利用脚本回放代替手工劳动,或者做对页面响应数的性能测试,Microsoft Web Application Stress Tool是个不错的选择。
   另外,在性能测试方面,PureLoad也是一个不错的工具,完全用Java写成,可以测试各种C/S程序,如SMTP Server等。这两个工具都是使用Post URL的方法测试Web Application的。对大量使用JavaScript的页面不太适合。当然,如果程序在Unix,linux下面运行的话,可以直接编写Shell 脚本程序,更加方便。
  另外,还有很多专门的工具,比如说Linkbot是专门作页面链接测试的。
  另外,测试流程管理工具也有不少,个人用过也一直在用的是Test Plan Control,短小精悍,不错。   至于WinRunner和LoadRunner之类,因为没有License,所以都没怎么用过,惭愧。不过我看过一篇英国人评价英国测试市场上最流行的五个软件的文章。WinRunner得分最高。
  测试工具从测试的方法上可以分为两种:白盒测试和黑盒测试   白盒测试工具主要有:
  内存资源泄漏检查:Numega中的bouncechecker,Rational的Purify等
   代码覆盖率检查:Numega中的truecoverage,Rational的Purecoverage,Telelogic公司的 logiscope, Macabe公司的Macabe等   代码性能检查:Numega中的truetime,Rational的Quantify等
  代码静态度量分析质量检查工具:logiscope和Macabe等
  黑盒测试工具主要有:   客户端功能测试:MI公司的winrunner,compuware的qarun,Rational的SQA robot等等
  服务器端压力性能测试: MI公司的winload,compuware的qaload,Rational的SQA load等等
  Web测试工具:MI公司的Astra系列,rsw公司的e-test suite等等
  测试管理工具:rational的test manager,compuware的qadirector等等,此外还有缺陷跟踪工具 trackrecord等。
  数据库测试工具:TestBytes
  黑盒测试工具:QACenter、SQATeamTest,Rational Viaual Test。
  回归测试工具:Rational TeamTest,WinRunner(MI公司)
  WEB系统测试工具:TEST,Workberch,Web Appication Stress Tool(WAS)
  白盒测试工具:Numega 、PuRe、软件纠错工具(Rational Purity)。
  嵌入式测试工具:Logiscope(静态测试工具)、CodeTest。
  系统负荷测试工具:RationalPerformance
  涵盖测试工具范围评估工具
  软件性能测试工具:LoadRunner(MI产品)、Rational Visual Qantify
  测试管理工具:TestDirector(MI产品支持整个生命周期中测试流程管理)

posted @ 2006-07-24 11:21 高山流水 阅读(1170) | 评论 (0)编辑 收藏

大学课程在线: http://realcourse.grids.cn/
学习在线:   http://www.eimhe.com/
http://www.bbb123.com/
视频下载和课件教程在线
www.1110.net/down.asp?UserID=190708

免费课件、教案、论文、试卷、在线考试的好地方
www.soabc.net/plug-ins/ad/get.asp?get=88312
 论文下载的好地方:维普数据库[申请加精]

http://vip.fjinfo.gov.cn/index.asp
www.eimhe.com 计算机,外语,学习,资料,视频,课件,下载
账号  chaoda
密码  chaoda

以下为考研用啦

http://www.studydown.com/

http://www.exam8.com/      
http://www.china-school.net/
http://www.eol.cn/

http://www.cnedu.cn/   考研教育网
http://www.chinayz.com.cn/index.htm
http://www.chinakaoyan.com/
http://www.eimhe.com/ 学生资源网

2005年硕士生录取查询网址 http://www.math.9.cn/

posted @ 2006-06-28 14:14 高山流水 阅读(638) | 评论 (2)编辑 收藏

一:校园文学
1
《草样年华》男的朝三暮四,优柔寡断,女的太完美(大学时期允许自己犯错,却总是希望爱人是女神。。)后来的续集就让人骂了,一直装不成熟总得有个头啊。
2
《 那一季的青春张扬》。。。。入学时遇到了在医院实习的校长的女儿,后来喜欢上另一个爱着一个将来留学的学长的女生,然后悲剧收场,女生怀孕然后毕业然后嫁人,主角一无所获,最初的小丽投奔了自己的设友。比较好的反映了爱自己的人和自己爱的人这个题材。缺点是描写有时过于戏剧性。
3
《忘记名字2》。。。。主角入学先是跟饭店老板娘发生暧昧,然后喜欢上了自己高一级的系花,之后开始了“追逐战”,在自己成功的时候女主角也毕业了,爱情终于符合经典理论,女主角选择了现实,男主角陷入了痛苦。结尾不好,竟然遇到了自己曾经暗恋描述的像神一样的高中女同学,人生好像顿悟,明显做着yy到了不能自拔得境界了。。。。
4
《忘记名字3》。。。。主角进入大学伊始便开始幻想自己得爱情,首先描述了开课时给自己留下好印象得a,大一疯狂一段后找到了自己高中同学b,两人为恋爱而恋爱最终无果而终,不过这段描写很搞笑,也很写实,后来痛定思痛。。。。。(记不清了)
通过交笔友写信认识了a得妹妹,之后两人竟然产生了青瑟得感情,理性与冲动得矛盾斗争之后,没有走到一起
这段情节是我看到得这些校园小说里最美好得一段(跟赵老师得美好不一样:P)。
文章中很多生活经历得描写都很棒,幽默风趣故事性也很强。最后写毕业分离得一章也很精彩。

跟后来看到的网络小说故弄玄虚,卖弄感情赚人同情比(比如《和空姐同居的日子》,这种小说看的过程有被作者耍的感觉,没意思,上过一次当就不会再上了),校园小说还是很纯的,没有那种商业气。
上面想不起名字的小说如果谁能记得一定告诉我,谢谢了。
其它的以后再补。

posted @ 2006-06-28 10:20 高山流水 阅读(327) | 评论 (0)编辑 收藏

仅列出标题
共30页: 1 2 3 4 5 6 7 8 9 Last