科学网

 找回密码
  注册

tag 标签: 程序设计

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

[转载]10分钟学会Python
yanxiaoyong 2010-6-23 20:52
按 :这三天密集监考,没有大块的时间干正事,就一口气写了5篇《 复杂网络分析库NetworkX学习笔记 》,看点击量估计会有朋友有兴趣学习这个库,但可能很多朋友都没有接触过Python。我以前也说过,Python一点也不难学,可以说是我接触过的最简单的编程语言了(我前后学用过C、C++、C#、Basic四门语言,现在则主要用Python)。为了方便感兴趣的朋友学习Python,我上网搜索了一些Python教程,大厚本的语法书估计各位都比较忙,也没时间看,我就专找那种速成性的,还真找到一些:有《 24小时学会Python 》、《 1小时学会Python 》,还有这个《 10分钟学会Python 》(英文原版见 http://www.korokithakis.net/tutorials/python )。咱就来最快的吧:10分钟学会它! 以下是转载的全文(向原作者和译者表示感谢):   1. 准备工作   哦,你是要学习Python编程语言但是又苦于找不到一个简洁但是全面 的教程么?这个教程就是要试图在10分钟内让你掌握Python。可能它有点不像一个教程,或者说应该介于教程和cheatsheet[可以快速查找的一 个简单表单,不知道怎么翻译,译注]之间,所以在这里我只能向你展示一些最基本的概念,旨在让你能够快速入门。显然,如果你真要学习一门编程语言,你需要 使用它编码一段时间。我假定你已经有一些熟知的编程知识,因此在这里我就不再讲那些与语言无关的编程知识。教程中的关键字我都让它高亮显示,这样你就可以 一眼就看清楚。另外,为了保持教程的简洁,一些知识就只在代码中展示,只有一些简单的注释。   2. 特性   Python 是一个强类型(也就是类型都是强制指定的),动态,隐式类型的(即,你不需要声明变量),大小写敏感(var和VAR是两个不同的变量),面向对象(一切 皆是对象)的语言。[专业术语翻译有点别扭,译注]   3. 语法   Python 没有命令结束标志,并且,使用缩进来区分程序块。块开始的时候缩进开始,块结束的时候缩进结束。声明需要一个:来引领一个缩进块。注释使用#开始并且只占 一行。多行注释使用多行字符串。赋值使用等号(=),测试是否相等使用两个等号(==)。可以分别使用+=或者-=来增加或者减少变量值。这在多 个数据结构上都适用,包括字符串。你也可以在一行上使用多个变量。举例来说: myvar = 3 myvar += 2 myvar -= 1 This is a multiline comment. The following lines concatenate the two strings. mystring = Hello mystring += world. print mystring Hello world. # This swaps the variables in one line(!). myvar, mystring = mystring, myvar   4. 数据类型   在Python中可用的数据类型有列表、元组以及字典。在集合库中集合 也可用。列表就像是以维数组(但是你还可以有列表的列表),字典就是关联数组(或者叫哈希表),元组就是不可变一维数组(Python中数组可以是任何类 型,因此你可以在列表、字典或者元组中混合使用数字、字符串等数据类型)。在所有的数组类型中第一个元素的标号都是0,负数表示从后向前数,-1则表示最 后一个元素。变量可以指向函数。用法如下: sample = , (a, tuple)] mylist = mylist = List item 1 again mylist = 3.14 mydict = {Key 1: Value 1, 2: 3, pi: 3.14} mydict = 3.14 mytuple = (1, 2, 3) myfunction = len print myfunction(mylist) 你可以使用:取到数组的一个范围,:前留空则表示从第一个元素开始,:后留空则表示直到最 后一个元素。负值表示从后索引(即-1是最后一个元素)。如下所示: mylist = print mylist print mylist print mylist print mylist 5. 字符串   字符串可以使用单引号或者双引号,你可以在使用一个引号的里面嵌套使用另一种引号(也就是说,He said 'hello'.是合法的)。多行字符串则使用三引号(单双皆可)。Python还可以让你设置Unicode编码,语法如下:uThis is a unicode string.使用值填充一个字符串的时候可以使用%(取模运算符)和一个元组。每个%s使用元组中的一个元素替换,从左到右。你还可以使用字典。如下 所示: print Name: %snNumber: %snString: %s % (myclass.name, 3, 3 * -) Name: Poromenos Number: 3 String: --- strString = This is a multiline string. # WARNING: Watch out for the trailing s in %(key)s. print This %(verb)s a %(noun)s. % {noun: test, verb: is} This is a test. 6. 流程控制   流程控制使用while,if,以及for。没有select[和哪种语言对比?不知道。译 注],使用if代替。使用for来列举列表中的元素。要得到一个数字的列表,可以使用range(number)。这些声明的语法如下: rangelist = range(10) print rangelist for number in rangelist:   # Check if number is one of    # the numbers in the tuple.   if number in (3, 4, 7, 9):     # Break terminates a for without     # executing the else clause.      break   else:     # Continue starts the next iteration      # of the loop. It's rather useless here,     # as it's the last statement of the loop.     continue else:   # The else clause is optional and is   # executed only if the loop didn't break.    pass # Do nothing if rangelist == 2:   print The second item (lists are 0-based) is 2 elif rangelist == 3:   print The second item (lists are 0-based) is 3 else:   print Dunno while rangelist == 1:   pass 7. 函数   函数使用def关键字。可选参数在必须参数之后出现,并且可以被赋一默认值。对命名参数而言,参数名参数 名被赋一个值。函数可以返回一个元组(打开元组你就可以实现返回多个值)。Lanbda函数是个特例,它由一个表达式构成。参数使用引用传递,但是可变类 型(元组,列表,数字,字符串等等)不能被改变。举例如下: # arg2 and arg3 are optional, they have default values # if one is not passed (100 and test, respectively). def myfunction(arg1, arg2 = 100, arg3 = test):    return arg3, arg2, arg1 ret1, ret2, ret3 = myfunction(Argument 1, arg3 = Named argument) # Using print with multiple values prints them all, separated by a space. print ret1, ret2, ret3 Named argument 100 Argument 1 # Same as def f(x): return x + 1 functionvar = lambda x: x + 1 print functionvar(1) 8. 类 Python部分支持类的多重继承。私有变量和方法可以使用至少两个_开始并且至少一个_结束来声明,比 如__spam(这只是约定,语言中并没有强制规定)。我们可以给类的实例赋任意的变量。请看下例: class MyClass: common = 10 def __init__(self): self.myvariable = 3 def myfunction(self, arg1, arg2): return self.myvariable # This is the class instantiation classinstance = MyClass() classinstance.myfunction(1, 2) 3 # This variable is shared by all classes. classinstance2 = MyClass() classinstance.common 10 classinstance2.common 10 # Note how we use the class name # instead of the instance. MyClass.common = 30 classinstance.common 30 classinstance2.common 30 # This will not update the variable on the class, # instead it will create a new one on the class # instance and assign the value to that. classinstance.common = 10 classinstance.common 10 classinstance2.common 30 MyClass.common = 50 # This has not changed, because common is # now an instance variable. classinstance.common 10 classinstance2.common 50 # This class inherits from MyClass. Multiple # inheritance is declared as: # class OtherClass(MyClass1, MyClass2, MyClassN) class OtherClass(MyClass): def __init__(self, arg1): self.myvariable = 3 print arg1 classinstance = OtherClass(hello) hello classinstance.myfunction(1, 2) 3 # This class doesn't have a .test member, but # we can add one to the instance anyway. Note # that this will only be a member of classinstance. classinstance.test = 10 classinstance.test 10 9. 异常处理 Python中的异常处理使用try-except 程序块: def somefunction(): try: # Division by zero raises an exception 10 / 0 except ZeroDivisionError: print Oops, invalid. fnExcept() Oops, invalid. 10. 包的导入 使用import 导入外部包,你也可以为单独的函数使用from import 这种形式来导入。下面是一个例子: import random from time import clock randomint = random.randint(1, 100) print randomint 64 11. 文件I/O Python有一个很大的内建库数组来处理文件的读写。下面的例子展示如何使用Python的文件I/O来序列化(使用 pickle把数据结构转换成字符串)。 import pickle mylist = # Open the file C:binary.dat for writing. The letter r before the # filename string is used to prevent backslash escaping. myfile = file(rC:binary.dat, w) pickle.dump(mylist, myfile) myfile.close() myfile = file(rC:text.txt, w) myfile.write(This is a sample string) myfile.close() myfile = file(rC:text.txt) print myfile.read() 'This is a sample string' myfile.close() # Open the file for reading. myfile = file(rC:binary.dat) loadedlist = pickle.load(myfile) myfile.close() print loadedlist 12. 其他 条 件语句可以链接使用。1 a 3检查a是否介于1和3之间。 可以使用del删除数组中的元素或者变量。 List comprehensions[不知怎么翻译,译注]提供一个强大的方法来创建和操作list(列表)。它由一个后跟一个for语句的表达式组成,这个 for语句后跟一个或者多个if@ 或者 @for语句,就像这样: lst1 = lst2 = print print # Check if an item has a specific property. # any returns true if any item in the list is true. any(i % 3 for i in ) True # Check how many items have this property. sum(1 for i in if i == 3) 3 del lst1 print lst1 del lst1 全局变量可以声明在函数外边并且不需要任何特殊 的声明就可以直接读取使用。但是如果你要改变该全局变量的值,你必须在函数的开始使用global关键字声明它,否则,Python将创建一个局部变量并 给他赋值(要特别注意这点,不知道的话很容易犯错)。比如: number = 5 def myfunc(): # This will print 5. print number def anotherfunc(): # This raises an exception because the variable has not # been assigned to before printing. Python knows that it a # value will be assigned to it later and creates a new, local # number instead of accessing the global one. print number number = 3 def yetanotherfunc(): global number # This will correctly change the global. number = 3 13. 结束语 这个教程并没有列出Python的全部细节(甚至连一个子集都算不上)。Python还有一系列的库以及许多其他功能,这就需要你通 过其他途径来学习了,比如很优秀的在线教程Dive into Python。我只希望这个教程能让你对Python快速上手。如果你觉得有什么需要改进或者添加的地方,或者你想看到的其他任何东西(类,错误处理,任 何东西),那就在这里留言吧。
个人分类: Python|9709 次阅读|2 个评论
Ocaml 程序设计
sunxs 2010-5-20 09:15
Ocaml简介。 Ocaml是一种函数式程序设计语言,属于ml类语言,此类语言包括sml、mosml等。函数式编程语言还包括lisp、haskell等等。 函数式编程语言的主要特点是贴近数学概念,更容易为数学家所掌握,相对而言,编程难度比汇编等语言要低,一般包含垃圾回收等内存管理功能,减轻编程负担。但是效率不高。一般需要通过一个解释器来执行。Ocaml一大特色就是支持命令式语言的编程,并且可以编译为机器代码,不需要单独的解释器来运行,效率明显提高。不过据报道,Ocaml的效率主要还是通过命令式特色来实现的。命令式编程语言包括C、C++、Java等等。 Ocaml在形式化领域应用较为广泛,比如CIL,一种C编译器前端就是用Ocaml编写。大量的程序分析、定理证明等学术工具是用Ocaml编写,也有大量的使用sml编写。另外,一种合并了电驴和bt的下载软件mldonkey也是用Ocaml编写的。 Ocaml可以编写可控制台(终端命令行)程序,也可以开发各种图形界面程序,开发网络程序。 Ocaml支持极为强大的模块化程序设计。 Ocaml支持面向对象的程序设计。 Ocaml具有较为丰富的编程库。 Ocaml可以调用C代码的连接库。C也可以调用Ocaml的库文件。 Ocaml在国内材料不多,特别是国内的主要程序设计都是基于C来展开的,对函数式编程非常陌生,习惯C的编程思路的对这种代码反而很不适应。 实际上,函数式编程很可能代表未来软件开发的主要方向,微软也在凑热闹,推出一款F#,一种跟Ocaml很类似的函数式语言。
个人分类: 未分类|8 次阅读|0 个评论
GISDK典型程序实例之:非直线系数计算
热度 1 yanxiaoyong 2010-4-29 11:50
本文摘自我编写的教材《 交通规划软件实验教程(TransCAD 4.X) 》中的8.3.3节(有修改),是一个用来计算公交线路非直线系数的GISDK程序。 线路非直线系数是指公交线路长度与首末站之间空间直线距离之比。公交线路的长度可以直接通过线图层Length字段获取,因此计算的关键是求出线路首末站之间的空间直线距离。 一种简单的方法是用工具栏中的尺子按钮测量每条线路两端点之间的空间直线距离,然后用线路长度除以这个距离就可以计算出一条线路的非直线系数。但当线路较多时用这种方法非常耗费时间,同时精度取决于鼠标点击位置的准确性。另外一种快速但稍复杂的方法,就是使用TransCAD内置的宏语言GISDK实现这一功能。下面给出用GISDK编程计算线路非直线系数的方法。 首先在Windows下新建一个文本文件,将其名称改为NLFactor.rsc,注意扩展名必需为rsc而不是txt。用记事本打开这个文件,在其中输入以下代码: Macro NLFactor //宏名称 //定义一个数据视图view,名称为Route System view=Route System //将Route System置为当前图层 SetLayer(view) //定义视图集view_set,其中包含了一个视图view view_set = view + | //得到视图集中的第一条记录 rec = GetFirstRecord(view_set, null) //外层循环开始,遍历视图集中的所有记录 while rec null do //根据视图中的字段ID得到线对象,返回该线对象的所有特征点 pts = GetLine(view.ID) //定义一个距离变量,用于储存线对象长度 length = 0 //内层循环开始,遍历线对象的所有特征点 for i = 1 to pts.length - 1 do //计算相邻两个特征点之间的距离并累加得到线对象长度 length = length + GetDistance(pts , pts ) end //内层循环结束 //计算线对象两端点之间的空间直线距离 dist = GetDistance(pts , pts ) //线对象长度除以端点空间直线距离,得到线路非直线系数 fac= length/dist //将该系数值写入Route System图层的NLFactor字段中 view.NLFactor=fac //得到视图集中的下一条记录 rec = GetNextRecord(view_set, null, null) end //外层循环结束 //计算结束,弹出提示框 ShowMessage(Success!) endMacro //宏结束 输入上述代码后,保存NLFactor.rsc文件,然后启动TransCAD,打开要计算非直线系数的线类型地理文件,然后运行这个宏就可以。具体方法参看我的上一篇文章《 GISDK典型程序实例之:线数据重采样 》。注意线图层中增加一个字段NLFactor,用于存放计算后的线路非直线系数。
个人分类: 程序设计|10843 次阅读|5 个评论
GISDK典型程序实例之:线数据重采样
yanxiaoyong 2010-4-28 20:52
在实际项目中用TransCAD绘制路网时,一般是先从AutoCAD等软件中导入路网地图,然后再进行一些后续的编辑工作。但有些地图(特别是扫描后数字化的地图)经常会遇到这样一个问题:很多线段会含有很多不必要的轮廓点,手工一个个去除是非常费事的,也很让人心烦。 我以往处理这种情况,都是先把AutoCAD地图导入SuperMap中,然后用线对象重采样的工具把多余的轮廓点去除掉,然后再保存为Shp格式导入到TransCAD中。但多种数据格式之间导来导去,难免会造成地图失真。而且,如果没有SuperMap或ArcInfo等具有曲线重采样功能的软件,就束手无策了。 这个问题我在TranBBS论坛上问过很久了,一直没人回答,于是我就自己动手,用TransCAD软件自带的GISDK开发工具实现了这一功能。 曲线重采样有很多方法,比较高效的是DouglasPeucker算法,不过我在GISDK里没找到函数参数传址的功能,试验了一下没能实现DP算法,于是就采用了一种比较简单的算法:垂距法。 关于垂距法的具体思路可以参看这篇博文:《 矢量数据的压缩 》,一般的GIS教材上也都会有 曲线重采样 算法的介绍,原理都非常简单。下边直接上代码: //TransCAD下的线数据重采样代码,基于垂距法 Macro SIM view=New Layer //数据视图view名称为New Layer, 请根据实际的线图层名自行修改 SetLayer(view) //将New Layer置为当前图层 view_set = view + | / /定义视图集view_set,其中包含了一个视图view rec = GetFirstRecord(view_set, null) //得到视图集中的第一条记录 while rec null do //遍历视图集中的所有线对象记录 linepts = GetLine(view.ID) //根据ID得到线对象的所有特征点 tolerance = 1 //定义一个限差tolerance,单位与地图单位相同, 请根据要求自行修改 newpts = RunMacro(Offset, linepts, tolerance) //调用垂距法,返回一个点数组newpts ReshapeLink(view.ID, newpts, null) //用返回的点数组更新线对象 rec = GetNextRecord(view_set, null, null) //得到视图集中的下一条记录 end RedrawMap() //重采样结束,刷新视图 endMacro //垂距法的子程序 Macro Offset (pts, tol) star = 1 //定义起始位置 ret: //如果未检查的点少于两个则不再检查,返回点数组 if (pts.length - star) 2 then do return(pts) end //顺序拾取三点执行检查 ,计算中间点到两端点连线的垂距 dist = GetLineDistance(pts , {pts ,pts }) if dist tol then do //如果垂距小于限差,则可去除这个点 pts = ExcludeArrayElements(pts, star+1, 1) end else do //否则保留该点,将检查点下移一位 star = star+1 end goto ret //调回函数开头,继续执行下一步检查 endMacro 在一个文本文件中输入上述代码后,把它保存为一个以rsc为扩展名的文件,就可以在TransCAD中运行了,具体方法如下: 在TransCAD中打开含有要进行重采样的线类型地理文件,然后选择Tools Add-Ins菜单项,TransCAD会弹出一个Add-ins对话框,选择列表框中的GIS Developers Kit,点击OK,此时TransCAD中出现了一个GISDK Toolbox工具栏。点击该工具栏左起第一个按钮,打开刚才建立的宏代码文件SIM.rsc,然后再点击第二个按钮,此时TransCAD弹出一个Test an Add-in对话框。在该对话框中,Name后输入 SIM ,即我们建立的宏代码的名字,然后点击OK。此时TransCAD将会运行这个宏代码,完成曲线重采样并自动刷新地图。 注意一开始可以把tolerance设得小一些,运行后不满意可以逐步调大,千万不要一开始就设一个很大的值。另外本代码没有经过严格测试,应用前请先备份数据,万一出错了不要来找我噢:)
个人分类: 程序设计|8749 次阅读|2 个评论
从C#到Python (pdf整理版)
热度 1 yanxiaoyong 2010-4-5 21:43
本文整理自我在博客园( http://www.cnblogs.com/yanxy/ )上发表的《从C#到Python》系列连载文章。原文从2010年2月25日开始写作,到4月5日全部完工。现将这篇连载整理成pdf文档,方便感兴趣的朋友下载阅读或打印。与原版本相比,这个整理版在语句上略有一些修改,删掉了一些废话,个别章节进行了少许调整。 写这个文章的目的,一方面是整理下我自己学习Python的心得体会,留着以后忘记时备查;另一方面就是希望能对有一定C#编程基础、同时对Python感兴趣的朋友有所帮助。 下载地址: CSharp.2.Python.By.YanXY.pdf 附:全文目录 0 前言:进入Python的世界 1 0.0 写在前面 1 0.1 安装和配置Python开发环境 1 0.2 第一个程序:Hello, world! 1 0.3 认识二者最基本的差异 3 0.4 小结 4 1 变量和数据类型 5 1.1 变量声明和定义 5 1.2 简单数据类型 6 1.3 高级数据类型 8 1.4 小结 12 2 运算符、表达式和流程控制 13 2.1 运算符和表达式 13 2.2 流程控制语句 15 2.4 动态表达式 19 2.5 小结 19 3 函数及函数编程 21 3.1 函数的定义 21 3.2 函数的参数 21 3.3 函数文档 23 3.4 函数编程 24 3.5 小结 26 4 类及面向对象 27 4.1 类的定义与实例化 27 4.2 类的成员变量 27 4.3 类的方法 30 4.4 类的继承 32 4.5 获取对象的信息 33 4.6 本章小结 34 5 模块和包 36 5.1 模块 36 5.2 包 37 5.3 本章小结 38 参考文献(推荐读物) 39
个人分类: Python|21899 次阅读|5 个评论
从C#7(2002)到C#9(2008)
donghy 2010-3-26 15:55
安装好了Visual Studio 2008,怎样使用原有的资源呢? 找到Visual Studio 2002下编写的C#程序,目录如下: 注意Balloon.sln的图标: 有一个7的标识。 双击Balloon.sln,启动C# IDE。出现Visual Studio转换向导如下提示: 单击下一步,出现创建备份对话框,如下所示: 默认地,已经选中了在转换前创建备份,并选定了备份位置。由于事先我们已经做好了备份,此处选择否。然后单击下一步,出现转换准备就绪对话框,显示如下: 此时应遵从提示,检查摘要。如果有误,可以退回上一步。无误,单击完成,转换结束。显示如下: 单击关闭即可。 如果关闭之前勾选了关闭向导时显示转换日志,显示如下: 如果关闭之前没有勾选,显示如下: 切换到文件夹目录窗口可以看到转换之后的目录如下: 看到醒目的9字标识了吧!
个人分类: 软件开发技术|3466 次阅读|0 个评论
介绍几个图论和复杂网络的程序库 —— BGL,QuickGraph,igraph和NetworkX
热度 6 yanxiaoyong 2010-2-24 12:05
刚加入 复杂网络圈子 ,暂时还没有成熟的研究内容,先发个资料性的东西占坑:) 作复杂网络研究离不开对各种实际或模拟网络的统计、计算、绘图等工作。对于一般性的工作,我们可以用 Pajek 、 Netdraw 和 Ucinet 等软件完成。但对一些特殊应用(比如自己开发了一个新模型),现有的软件不能提供相应的建模或计算功能,这时就必须要通过编程的办法来解决问题了。 在这篇文章中,向大家介绍我使用过的4个面向图论及复杂网络分析的程序库,它们可以(分别或同时)用C、C++、C#和Python等语言调用。同时这些库都是开源的,可以通过研读它们的源代码提高编程水平。 好,下边开始介绍,第一位出场的是: 一、Boost Graph Library 准C++标准库 Boost Graph Library(BGL)是C++ Boost库的成员之一。Boost是一个经过千锤百炼的C++库,作为标准模板库STL的后备,是C++标准化进程的发动机之一。Boost库由C++标准委员会库工作组成员发起,在C++社区中影响甚大,是不折不扣的准标准库。 BGL的特点是灵活性和高运行效率。BGL是以模板的形式提供的,这意味着你可以在模板的基础上创建自己的类型,比如自定义的节点类。BGL的开发者是世界上最顶尖的C++专家,这个库中实现的各种图算法具有非常高的执行效率,而且BGL本身具有工业强度,你可以放心的使用它。此外,BGL的代码结构良好,是非常值得研读的精品,对于学习算法与数据结构会有很大的帮助。 从我的角度来看,BGL的缺点是没有提供复杂网络分析的算法,所以在实际中我使用的还不多。建议对于分析大规模的网络问题时使用这个库,利用它良好的图数据结构,开发自己的复杂网络分析算法,将会获得很高的执行效率。 参考资源: BGL官方网站: http://www.boost.org/doc/libs/1_42_0/libs/graph/ 技术书籍《The Boost Graph Library》,作者: Jeremy G. Siek,Lie-Quan Lee,Andrew Lumsdaine,见: http://www.douban.com/subject/1463103/ 《使用Boost Graph library》,一个简短的BGL使用介绍,适合快速上手,见: http://www.cppprog.com/2009/0408/100.html 《Boost Graph Library 学习笔记》,讨论学习BGL中遇到的问题,见: http://blog.csdn.net/magicblue/archive/2009/05/22/4208976.aspx 二、QuickGraph .NET平台下的BGL QuickGraph是一个用C#语言编写的.NET组件库,所提供的算法与BGL类似,可以看作是Boost Graph Library在.NET平台下的实现。目前QuickGraph的最高版本是3.3,支持.NET 2.0和.NET 3.5平台。 对于复杂网络研究,QuickGraph能够提供的帮助与BGL基本类似。如果你对C#语言(以及其它支持.NET的语言)比较熟悉,可以考虑选择这个库。但由于.NET程序是在虚拟机下运行的原因,所以效率不够高,不适合处理大规模的计算问题。 参考资源: QuickGraph官方网站: http://www.codeplex.com/quickgraph 中文资料暂时还找不到。 三、igraph C语言写的复杂网络分析库 igraph是一个建立和操纵无向图、有向图的开源C程序库,它既包含经典图论里的各种算法(例如最小支撑树、网络流等),也包含了最近的出现的一些网络分析算法(如社团结构搜索等)。 igraph是C写的,这意味着你很容易在C/C++中使用它。如果你不熟悉这两种语言,或者觉得用C/C++太繁琐的话,igraph还提供了R语言(一种国外很流行的统计分析语言)和Python语言的接口,所以也很适合科研人员使用(我现在用的是Python,调用igraph很简单)。 参考资料: igraph官方网站:http:/ /igraph.sourceforge.net/ 关于Python语言的介绍,见: http://zh.wikipedia.org/wiki/Python 关于R语言的介绍,见: http://zh.wikipedia.org/wiki/R语言 四、NetworkX 全面支持复杂网络分析的Python包 NetworkX是一个创建和操纵复杂网络,并对复杂网络的结构、功能和动力学进行研究的Python包,它提供了目前应用最广泛的一些复杂网络分析算法,当然也包括基本的经典图论算法。NetworkX目前只能在Python语言中使用(这也是我学Python的原因之一,见《 从C#到Python 谈谈我学习Python一周来的体会 》)。 我个人认为NetworkX比igraph要好用,因为NetworkX的文档更清晰易读,程序结构组织得也很好,我现在主要在用这个包。但NetworkX的执行效率多数情况下会比igraph要低(见Drew Conway所作的对比: http://files.meetup.com/1406240/sna_in_R.pdf )。所以也不适合作太大规模的网络分析计算。此外,NetworkX和Python的一个绘图包Matplotlib结合得很好,可很方便地进行复杂网络可视化。 参考资源: NetworkX官方网站: http://networkx.lanl.gov/ Matplotlib(科学绘图的Python包): http://matplotlib.sourceforge.net 五、总结 本文介绍了图论与复杂网络研究常用的一些程序库。用好这些程序库(以及其它一些软件工具),可以避免我们无谓的re-invent the wheel,从而提高工作效率。在网上了解到,国外同行用这些库的很多,而在国内还很少搜索到这方面的资料(除了BGL)。作为我进复杂网络圈的敲门砖,向各位圈友推荐这几个库。另外,我近期正在学习Python和NetworkX,如果您感兴趣,欢迎和我交流:) 附:几个库的开发及调用语言对比(*看来学Python还是不错的,这几个库都可以调用-_-) 库名称 原始开发语言 可用某语言调用 BGL C++ C++/ Python(通过boost-python) QuickGraph C# 支持.NET平台的任何语言(Python程序员可用IronPython) igraph C C/C++/R/Python(理论上至少有50种语言可直接或间接调用C程序) NetworkX Python Python
个人分类: 复杂网络|43257 次阅读|45 个评论
我的第一个Python程序——删除代码前行号的小工具
热度 1 yanxiaoyong 2010-2-24 09:01
(根据我在 博客园 上连载的四篇文章整理,见 http://yanxy.cnblogs.com ,转载请注明出处) 近两天内的目标是在我博的每个栏目发一篇文章,先都占个坑再说,空着不好看:) 《程序设计》这个栏目里,就从我刚开始学的Python开始吧。 一、引言 Python是一种简单却又强大的语言,我觉得它很适合非专业程序员(特别是科研人员)使用。比如作一些科学计算、数据处理工作等,Python简单的语法和丰富的第三方库可以有效帮助我们提高工作效率。 本文并不主要介绍Python编程的语法,或Python怎么安装、运行、调试等,有兴趣可以到科学网 潘超的 Blog 去看看,那里有一些不错的入门资源。整理这篇文章的主要目的还是想介绍下我学、用Python的一些体会,希望能为大家提供借鉴。我学Python已经有十多天了,现在已经初步掌握了Python。我认为好的学习方法不光是看书或上网查资料,最好是能结合一个实际的例子一点点去深入,这样掌握起来会更快更牢。我在写了Hello World之后,第一个正式编的程序就是下面这个复制代码时去除行号的小工具。 二、分析与设计 现在很多专业计算机技术网站提供的各种源代码前,很多会带有数字行号。我们将这些代码复制下来运行前,要一行一行的去删除前面的代码,即浪费时间又容易出错。如果有一个程序能快速、正确的去除掉代码前的行号,无疑可以节省我们的很多时间(当然我写这个程序花了大概有10几个小时,不过正所谓磨刀不误砍柴工嘛:)。 网上代码前的行号排列大都比较有规律,多数采取如下形式: 1. abc 2. def 或 1 abc 2 def 以及 、1:、(1)等。 因此,要去除行号,首先就是要查找到每行的开头数字及前后分割符号,然后替换掉他们。根据这个思路,很容易写出如下的基本程序框架: 第1步:读取全部n行代码到一个字符串,然后将其转换为包含n个子字符串的数组(或列表); 第2步:对于每一个子字符串,从左至右开始查找每个字符,如果找到一个或多个连续的、可转换为整数的字符,就删除其左侧(包含数字自身位置)的全部字符,并用剩余部分生成一个新字符串。 第3步:如果新字符串左侧有空白或:.])等分割符号,就去除掉它们,再用剩余部分生成一个新字符串。 第4步:将所有处理过的字符串顺序连接起来,得到一个字符串,返回处理行号后的源代码。 三、初步的实现字符串替换 由于Python语言提供了良好的字符串操作功能,因此很快可以写出一个初步的版本: # 代码 1 # -*- coding: utf-8 -*- def CutLineNum(inStr): # 用def关键字声明函数,注意后边加冒号 multiStr = inStr.splitlines(1) # 将多行文本拆分为文本列表 outStr = u '' for singleStr in multiStr: # 循环用for in的结构,后边也加冒号 singleStr = singleStr.lstrip() # 去除左侧空白 i=0 # 迭代算子 for charStr in singleStr: # 从左至右循环查找字符 if charStr.isdigit(): # 如果判断是数字类型 i += 1 # 迭代算子加1 elif i0: # 找到了一个非数字字符,而且前边已有数字字符 singleStr = singleStr # 返回从该位置起的剩余字符 break # 跳出循环 else : # 如果都没有,说明是空行 break # 跳出循环 outStr += singleStr # 将所有行组成完整代码 return outStr # 返回 (注意, # -*- coding: utf-8 -*- 是使用utf-8编码,可以支持中文字符) 以上代码实现了基本程序框架中的1-3步,第4步由于情况较复杂(有的行号后有分割符,有的没有,而且空格数量也不一样),所以暂时用以下函数手工处理: # 代码 2 # -*- coding: utf-8 -*- def CutLeftChar(inStr): outStr = u '' multiStr = inStr.splitlines(1) for singleStr in multiStr: singleStr = singleStr outStr += singleStr return outStr 这样虽然苯拙一点,但至少解决了问题。 四、进一步优化正则表达式替换 正则表达式(Regular Expression,简称Regex),是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。关于Python中正则的入门材料可以参考《 正则表达式30分钟入门教程 》, (不过我觉得30分钟掌握正则表达式还是有困难的,为掌握它我还专门买了一本《精通正则表达式》)。正则表达式是一种处理文本的强大工具,删除代码行号对于它来讲是小菜一叠。下面用正则表达式改写代码1和2,如下: # 代码 3 import re # 导入Python的正则表达式模块 def CutLineNum (inStr): multiStr = inStr.splitlines(1) outStr = u '' p = re.compile(r '\D*\d+\s? |\)]?\s?' ) # 编译正则表达式 for singleLine in multiLine: outStr += p.sub( '' , singleLine,count = 1 ) # 用空字符替换每行的第一个匹配上述正则表达式的字符串 return outStr # 返回 累加后的 字符串 以上代码中的咖色部分就是一个Regex,它的含义是:0或多个非数字字符 + 至少1个数字字符 + 0或1个空白字符 + 0或1个分隔符(包括点、冒号、右圆/方括号,可添加其他分隔符) + 0或1个空白字符。 以上Regex符合大多数代码前行号的规则,删除行号就是用空字符替换掉每行代码中第一个匹配该Regex的字符串(注意只能是第一个,因为程序里可能会存在abc1.open等情况,如果全部匹配就会误删代码)。 五、继续优化采用函数编程 代码3看起来还不够简洁,没关系,Python是一种准函数编程(Functional Programming,FP)语言,做这种简化代码的事情最拿手。在这里,我用到了两种函数编程手段匿名函数(lambda)和一种高阶函数(map),将代码简化至一行,如下: # 代码 4 import re # 导入Python的正则表达式模块 outStr = '' .join(map( lambda x:re.compile(r '\D*\d+\s? |\)]?\s?' ).sub( '' , x,count = 1 ),inStr.splitlines(1)))) 这样代码就只优化到了一行了,是不是很简洁呢?当然代码的可读性受到一定影响。所以函数编程不能滥用。(滥用的例子可以见我的文章《 学习Python列表内涵:一行代码搞定双倍超立方数计算 》)。函数编程是个稍微复杂点的问题,我觉得掌握与否均可,所以就不很详细地去解释上述代码了。如果对Python的函数编程感兴趣,可以参考《 可爱的 Python:Python 中的函数编程 》,很不错的一篇文章。 六、完整的程序添加I/O 完整的程序肯定少不了输入输出功能。对于这个去除复制代码行号的小工具,我想到的输入输出方式一共有三种: 1、 文件方式 将复制的代码存为一个文本文件,然后用程序读取它,去掉行号后在写回文件。这种方法应该说是最不方便的,可以算一下自己需要点多少下鼠标麻烦,所以我没有实现它。关于Python的文件操作内容,网上有很多资料,可以搜索一下。 2 、窗口方式 将复制的代码粘贴到一个窗体的文本框里,然后点击按钮去除行号,再从文本框里把处理后的代码复制出来。这是比较常规的做法,我分别用wxPython和PyQt4实现了这项功能,源代码见 http://www.cnblogs.com/yanxy/archive/2010/02/19/YanxyFirstPython.html 。由于GUI编程是个比较复杂的问题,我就不详细展开了,以后有时间再写。 3 、剪贴板方式 复制代码到剪贴板后,启动处理行号程序,直接处理剪贴板内的文本,然后再复制到其他地方。这是最方便的一种方法,而且由于不用构建GUI,代码量也会很少。见下边: # 代码 5 # -*- coding: utf-8 -*- import win32clipboard as c #import 包的时候,如果包名太长,可以用as起一个别名 import win32con as w # 以上两个包都是专门针对windows平台的,注意 import re c.OpenClipboard() # 打开剪贴板 strList = c.GetClipboardData(w.CF_TEXT).splitlines(1) # 读取剪贴板内容到一个字符列表 c.EmptyClipboard() # 清空剪贴板 c.SetClipboardData(w.CF_TEXT, '' .join(map( lambda x:re.compile \ (r '\D*\d+\s? |\)]?\s?' ).sub( '' , x,count = 1 ),strList ))) # 将去处行号后的字符写回剪贴板,此处用到代码 3 c.CloseClipboard() # 关闭剪贴板 七、总结 以上就是我初学Python作的第一个程序,虽然很简单,但在编写这个程序的过程中,我学习到了: 1、Python的基本语法、类型与逻辑控制 2、Python的函数定以及函数编程方法 3、Python的图形用户界面设计(GUI) 4、正则表达式及其在Python中的应用 短时间内就可以学会这么多内容,足以说明Python的简单易学,你也应该能体会到Python的强大吧。此外,在完成这个程序的过程中,我所用到的基本思路是: 1 、由粗到细 先根据功能要求实现程序逻辑框架,然后用你所掌握的最基本方法实现初步版本,先让程序能用。在此基础上,再去看是否有继续优化的可能(从代码简洁性或效率两方面),逐步细化,这时候才是提高的过程。 2 、自内而外 先实现核心算法,再添加外围功能(I/O,GUI等)。有些编程初学者热衷于用IDE去拖拉控件、美化界面等(当然这项工作也是必要的),没有把更多精力集中到核心算法中去,这样不利于真正学好一门语言。 当然这个程序还有很多需要完善的地方,欢迎提出你的意见或建议。 如果需要了解更多关于Python的内容,可访问啄木鸟社区的《 Python 资源索引 》。
个人分类: Python|12012 次阅读|1 个评论
转载--乱弹程序语言
furaibo 2009-4-19 22:21
昨天在 Info 看到了对于 《学习新语言通常是在浪费时间》 的 讨论 ,描述了很多人对于学习新语言的观点,让我想起了以前ThoughtWork上看到的 《混合语言编程》 。我也来乱弹一下编程语言。 我觉得,语言,就像刀! 不同的刀用来做不同的事,而不同语言应对不同情景,只是语言的历史不像刀的历史那么源远流长,也就没有那么多花样。 不同类型的语言其实没有可比性,因为它们的理念完全不同,就像菜刀是用来做菜的,而金丝大环刀是用来杀人的。如果一个冷峻的刀客在与宿敌的巅峰对决中,凝视对手半个时辰之后抽出一把西瓜刀,那他的敌人肯定是笑死的。 《食色无双》一书中对食和色的描述令我叹为观止,我就斗胆拿厨艺类比编程,把程序员比作厨子,那么,语言就是程序员手中的刀。工业语言,C#、Java,就像普通的菜刀,切、剁、削、拍、雕,样样都成,无非顺手不顺手、效率高不高的问题;脚本语言,Ruby、Python,就像是雕花小刀,对付冷拼那是拿手好戏,但是用来剁肉馅肯定是和自个过不去;底层语言,C、C++,就像剁骨刀,大开大阖,威力无穷,用好了再硬的骨头也能啃得动,用不好就地小心自己的手指头。 当然不排除有厨子把刀法练到了覆履归一的极境,用汇编从头到尾开发一个企业级应用,那是一种执着、一种意境,常人永远无法企及。 同类型的语言学一种应该就够了,就像两把菜刀,大小款式各有不同,两把都用,大概哪一把都用不精;而不同类型的语言最好各学一种,使用水果刀切水果,使用剁骨刀切肉,才会事半功倍。 其实我们早就学会用不同的语言做不同的事情:访问数据库会写SQL、格式化页面会用CSS、交换数据会想起XML或许将来的一天,写Web就是Ruby、写网站就是XAML。 但世界上还存在一种叫瑞士军刀的东西,代表了毕功于一役的理念,现在的.Net俨然正在向这方面发展:用Linq代替SQl、用SilverLight代替Html,然后把动态语言也拉上了战车,大有一招鲜、吃遍天的架势。好与不好就只有各位看管自己心里知道。 而我的看法是,不要被刀光耀花了眼,挑一把趁手的,真正的体会它的意境,做到收放于心,圆融自然;当手里的家伙不好用的时候,也不要抱着磕死的信念和它死磕,或许不远处就有一把应景而生的利器。 但,刀,终究只是工具,用刀的人,才是根本,只有人境界到了,才能以无厚入有间,游刃有余!
个人分类: 书斋小记|2751 次阅读|1 个评论
2008年图灵奖揭晓,Barbara Liskov成为第二位女性桂冠得主
turing 2009-3-13 14:38
by 图灵刘江 转载请注明出处:http://blog.csdn.net/turingbook 【图灵本月主打书】 iPhone开发基础教程 Amazon榜首图书,让我们抢先拥抱软件开发的未来 Flex 3权威指南 来自Adobe公司的官方教程 刚才看 HackerNews 获悉,昨天, ACM(计算机学会)将 最新一届图灵奖颁发给了麻省理工学院的女教授 Barbara Liskov 。她将获得Intel和Google赞助的25万美元奖金。 这位美国第一位计算机科学女博士,如今成为了有史以来第二位女性图灵奖得主(第一位是前年得奖的 Frances Allen )。如果说前年和 去年 两届图灵奖得主我们很多同学都不熟悉的话,那么Liskov你要是没听说过,那就别大言不惭地说自己是程序员啦,面壁三天去先。什么?你不知道图灵奖?那,那你来CSDN干嘛? ACM网站正式的颁奖理由是: For contributions to practical and theoretical foundations of programming language and system design, especially related to data abstraction, fault tolerance, and distributed computing. (对编程语言和系统设计的实践与理论基础,尤其是数据抽象、容错和分布式计算方面的贡献。) Wikipedia上对她的简介是这样的(这个条目是我刚才写的,呵呵): 芭芭拉利斯科夫 (1939年),本名Barbara Jane Huberman。美国计算机科学家,2008年图灵奖得主,2004年约翰冯诺依曼奖得主。美国工程院院士,美国艺术与科学院院士。ACM会士。现任麻省理工学院电子电气与计算机科学系教授。 1961年在加州大学伯克利分校获得数学学士学位。1968年在斯坦福大学获得博士学位,她是美国第一个计算机科学女博士。导师为1971年图灵奖得主约翰麦卡锡,论文题目是国际象棋残局程序。 利斯科夫领导了许多重要的项目,包括小型低成本交互式的分时操作系统Venus,第一个支持数据抽象的面向对象编程语言CLU的设计与实现,第一个支持分布式程序实现的高级语言Argus,面向对象数据库系统Thor,还有最近的Byzantine分布式容错系统。其中,CLU语言对现代主流语言如C++/Java/Python/Ruby/C#都有比较深远的影响。而她从这些实际项目中提炼出来的数据抽象思想,已经成为软件工程中最重要的精髓之一。 她另外一个在程序设计中有广泛应用的成就,是与周以真(Jeannette Wing)一起提出的Liskov替代原则,是面向对象最重要的几大原则之一。 【图灵图书推荐】图灵奖得主著作:Jim Gray 事务处理:概念与技术(英文版) Ian Sutherland 高速CMOS电路设计:Logical Effort方法(英文版) 可以说,Liskov是历史上为数不多的与程序设计直接相关,或者说是程序员出身的图灵奖得主。她的博士论文就是一个程序,还是一个游戏程序嘛。而Liskov替代原则,只要你用面向对象,就很可能天天在用。 关于CLU语言,还可以多说几句。在Wikipedia CLU条目 上有这样的一段话: Python and Ruby borrowed several concepts from CLU (such as the yield statement and multiple assignment) CLU and Ada were major inspirations for C++ templates. CLU's exception handling mechanisms also influenced newer languages like Java and C++. All objects in a CLU program live in the heap, and memory management is automatic. These elements directly influenced Java. Python and C# include generators (iterators in C#), which first appeared in CLU as iterators. Lua took multiple assignment and multiple returns from function calls from CLU. 搜索了一下,国外有 DDJ 和 MIT 网站有报道。国内 新浪 和 搜狐 基本上就是翻译了上述外国网站上的内容,内容很业余,但是比起前几年过了多少天也没反应,已经强很多了。DDJ的报道还是比较深入的,还有一个小的QA: Q : When you began your career in computer science, it was still a relatively young field. How have you seen this discipline evolve over time -- at MIT and elsewhere? A : The change has been tremendous. When I started, most of the field was unexplored and there were obvious problems everywhere -- lots of low-hanging fruit, but also very fundamental issues that were poorly understood and very confusing. Today the field is on a very sound foundation. There are still many problems to work on, but now this work happens in the context of all that has gone before. When I started, this context was missing, so you just struck out on your own. Q : Looking back at your career, what is the single accomplishment of which you are most proud? A : Probably the development of the concept of data abstraction and the CLU programming language. This work was done at MIT in the 1970s. Q : Where do you plan to focus your research going forward? A : Today I am working primarily on distributed systems -- systems that run on many computers connected by a network like the Internet. My focus recently has been on the security of online storage. I believe that more and more users will store their information online, but the storage they use needs to be implemented so that they don't lose their information, their information is available when they need it, and they can be confident that their confidential information will not be leaked. Q : As the first woman to earn a PhD in computer science, what advice would you give to other women who are considering going into this field? A : I have found computer science to be a wonderful field to work in. I think the main reason is that the kind of thinking and problem-solving it requires matches my abilities. I believe that finding work to do that you like and are good at is the most important way to find a satisfying career. Young women (and young men) who find that computer science is a match for them should pursue it. There is lots of interesting work remaining to be done. Q : When you began studying computer science at Stanford, computers were big mainframes and the Internet was still in the distant future. Today, computers fit in the palm of our hands -- many are much smaller -- and the Internet is ubiquitous. Given that you have watched these transformations over the last five decades from a front-row seat, what do you think the next half-century will hold? A : I don't have a crystal ball! It seems obvious that computers and the Internet will continue to be very important to individuals, companies and society. But I don't know the exact form this will take. 【延伸阅读】 2007年图灵奖揭晓 Frances Allen荣获2006年图灵奖 帮助寻找图灵奖得主Jim Gray 图灵奖得主、FORTRAN之父逝世一位回头浪子的传奇人生
个人分类: 未分类|5419 次阅读|0 个评论
莎士比亚是程序员?
furaibo 2009-3-4 16:53
刚刚在 Sourceforge 上发现了一个称为莎士比亚的程序设计语言,感觉挺有意思的,在这里介绍给大家。 这个语言的最大特色就是它的源代码看起来象莎士比亚的剧本。它的所有变量必须是莎士比亚剧本中出现的人名(比如, Hamlet 等),操作符和控制语句也是剧本式的。编程的过程好像是模仿莎士比亚编剧似的。 呵呵,这样的语言用来做应用系统,估计比汇编语言的编程效率都低,有谁会用呢?可是,这种自娱自乐的心态还是值得肯定的。过一把编剧的隐吧。 如果您还有兴趣,请看: http://shakespearelang.sourceforge.net/
个人分类: 书斋小记|4068 次阅读|1 个评论
双语教学现在可以搞一搞了
胡俊峰 2009-2-22 14:02
概论课上使用C语言的原文教材,实行双语教学已经有4个学期了。大概经历了四个阶段:很辛苦-学生比较烦;较辛苦-学生能接受;一般辛苦-学生非常赞;正常辛苦-教师和学生已经基本无视什么是双语教学了。(当然,也是因为学生的英文水平普遍大幅提高了。) 连续4个学期的教学评估结果对照图: 能看出来,刚开始确实是不行的,后面则是逐年升高。特别是在第三学期,学校调整了教学评估的打分标准,课程普遍的评分大幅下降,而我这门课评估分数还是保持上升。 第四学期实验班的评估成绩很高多少含有本系学生对老师的鼓励因素,不能太当真。给外专业学生的计算机课采用双语教学能取得好的教学效果与评价还是能说明问题的。下面的链接给出了08年给生科院学生开课的评估意见,总体来看是相当正面的。从我个人的感觉来看,现在的学生英文基础越来越好,对采用原文教材也比较习惯了,如果条件成熟双语教学是可以搞一搞了。
个人分类: 生活点滴|3015 次阅读|2 个评论
汇编语言实验园地_10
求新 2009-2-16 12:30
实验9程序与实验10实验课题 实验10 利用子程序进行串处理及有关日期的程序设计 一、实验内容:利用子程序结构设计从串中查找一个字符的所有位置、查找一个字符串。宏汇编程序设计。 二、实验目的:1. 学习结构化程序设计方法。 2. 如何在一个串中查找到一个字符的所有位置。 3. 如何在一个串中查找到一个另一个字符串。 4. 认识宏的概念,学习宏汇编程序设计方法 三、实验题目 1. 要求自行设定二个字类型的串STRING1与STRING2的内容,用程序对这二个串进行比较,如果相等,0送BX,否则,0FFFFH送BX。设串长为COUNT。最后分别以16进制形式显示BX、STRING1与STRING2的内容。 思考:本题如果不借助串比较指令来做,需要怎样设计?要考虑一个串和另一个串不相同但前面有部分字符相同的情况。 以下两题为实验8第1题利用子程序结构求解的设计参考。 2. 已知程序段如下,将它补充完整,使能将结果(BX的值)以16进制形式在屏幕上显示,根据显示情况分析说明其功能是什么?要求将16进制显示程序段利用子程序进行设计。 DATA SEGMENT BUF DB AABAAAAABBCD COUNT EQU $-BUF DATA ENDS MOV AL, A MOV DI,OFFSET BUF MOV CX,COUNT DEC DI NEXT: INC DI CMP AL, LOOPE NEXT MOV BX,DI JNZ EXIT MOV BX,0FFFFH ;当ZF=1,CX=0时退出循环 EXIT:. 3. 对在STRING中搜索A的程序段进行补充设计,要求对设计加详细注释。要求自行设定一个长度COUNT的字节类型的串STRING的内容,用循环程序对这个串进行搜索,如果搜索到字节类型数据A,显示当前位置(字长)。STRING、COUNT、A的内容自行设计。 LEA DI,STRING MOV AL,A MOV CX,COUNT CLD REPNE SCASB JZ OK OK: 4. 在一个串中查找一个字符,显示查到该字符的次数。 5 用串指令在一个串中查找一个字符,显示所有查到位置的地址。如果没有欲查字符,显示-1。 6.在一个串中查找另一串,如果找到,将查到串的首地址存到DI中。 7.求编写显示系统的当前日期和时间的程序。要求程序运行时显示的信息格式为: Current date is 10-30-2008. Current time is 10:23:26.12 相关的DOS功能调用: 【获取系统当前日期】 调用指令:INT 21H 功 能 号:2AH 入口参数:无 出口参数:CX = 年(范围1980~2099) DH = 月(1~12) DL = 日 【获取系统当前时间】 调用指令:INT 21H 功 能 号:2CH 入口参数:无 出口参数: CH = 小时(0~23) CL = 分(0~59) DH = 秒(0~59) DL = 百分之一秒(0~99) 8. 设计一个万年历程序。已知2008年1月1日为星期二,求2008年之后21世纪的某年某月某日是星期几?不考虑输入错误。 分析:假设通过键盘分别输入公元年份(输入末二位)、月份(二位)、日期(二位),可以利用前面的子程序分别变成二进制数。再计算输入日期与2008年1月1日之间相差日数X,将X除以7的余数加2就代表星期几,7代表星期日,1代表星期1,。而要计算相差日数X,必须考虑闰年问题:4年一闰、百年不闰、400年闰。非闰年365天,2月份28天;闰年366天, 2月份29天。可以先分析年份之差,对每一年判断是否闰年,再加366或365;再分析月份之差,求出所求年内距离1月1日的天数。为了能用一个程序计算各个月的情况,设计一个表:ruler=31,28,31,30,31,30,31,31,30,31,30,31,每一个值代表一个月是大月还是小月,1表示31天,0表示30天,利用间址查表求天数。2月单独计算。为求程序清晰,分别设计了分析闰年、月份二个子程序,在求解星期几的程序中调用。 实验10参考程序段 1. 用循环指令在一个串中查找一个字符,第一次查到该字符时将地址放在DI中。 MOV AX,DATA MOV DS,AX MOV AL, 'A' MOV DI,OFFSET BUF MOV DX,0 MOV CX,COUNT DEC DI NEXT: INC DI CMP AL, JZ NEXT1 LOOP NEXT NEXT1: 2. 用串指令在一个串中查找一个字符,查到第一个时将位置放在DI中。 MOV AX,DATA MOV DS,AX MOV ES,AX MOV AL, 'A' MOV DI,OFFSET BUF MOV CX,COUNT REPNE SCASB JNZ EXIT DEC DI ;找到的存放地址放在DI中 3.在DAT1串中查找ADD2串的第1个字符(串长COUNT2),如果找到,将剩余串的首地址存到ADD1中,剩余串长度存到ADD2中。 MOV AX,DATA MOV DS,AX MOV ES,AX MOV ADD1,OFFSET DAT1 ;立即数传存储器 MOV AL,X ;取欲查之字符串第1个字符 MOV ADD2,COUNT2 CLD BACK1: MOV DI,ADD1 ;取欲查字串首地址 MOV CX,ADD2 ;取欲查字串长度 REPNE SCASB ;查找 MOV ADD1,DI ;保存剩余串首地址 MOV ADD2,CX ;保存剩余串长度 4.求系统的当前日期和时间分别放在DX与CX中的程序。假使在数据区FNAME保存一个文件的名字。其中DX 中存年月日的格式: 0-4位:日,5-8位:月,9-15位:年份-1980。CX中所存时间的格式: 0-4位:秒/2,5-10位:分,11-15位:时 MOV DX, OFFSET FNAME MOV AL, 2 ; 读写方式 MOV AH, 3DH ;打开文件 INT 21H MOV BX, AX MOV AH, 57H ; 读\改日期 MOV AL,0 ;0 表示读出时间,1表示改写时间 INT 21H MOV DI,CX 5.求以十进制方式显示DX(日期)内容的宏。 AXTOBCD1 MACRO PUSH SI PUSH DI PUSH CX MOV SI,DX ;DX 中存年月日 0-4位:日,5-8位:月,9-15位:年份-1980 ;保存CX中所存时间 0-4位:秒/2,5-10位:分,11-15位:时 MOV CL,7 ;年 ROL SI,CL MOV DX,SI AND DX,7FH ADD DX,1980 AXTOBCD DX MOV DL,'.' MOV AH,2 INT 21H MOV CL,4 ;月 ROL SI,CL MOV DX,SI AND DX,0FH AXTOBCD DX MOV DL,'.' MOV AH,2 INT 21H MOV CL,5 ;日 ROL SI,CL MOV DX,SI AND DX,1FH AXTOBCD DX MOV DL,'.' MOV AH,2 INT 21H POP CX POP DI POP SI ENDM 6.求以十进制方式显示DI(时间)内容的宏。 AXTOBCD2 MACRO PUSH SI PUSH DI PUSH CX MOV CL,5 ;时 ROL DI,CL MOV DX,DI AND DX,1FH AXTOBCD DX MOV DL,'.' MOV AH,2 INT 21H MOV CL,6 ;分 ROL DI,CL MOV DX,DI AND DX,3FH AXTOBCD DX MOV DL,'.' MOV AH,2 INT 21H MOV CL,5 ;秒 ROL DI,CL MOV DX,DI AND DX,1FH SHL DX,1 AXTOBCD DX MOV DL,'.' MOV AH,2 INT 21H POP CX POP DI POP SI ENDM 7. 求从键盘输入二个十进制数字变成二进制数子程序 ;子程序名:IMPOR ;程序功能:从键盘输入二个十进制数字变成二进制数 ;入口参数: ;出口参数: 二进制数:BX ;使用寄存器:AX IMPOR PROC MOV AH,1H INT 21H ;键盘输入1个字符,不考虑输入错 SUB AL,30H MOV BL,10 MUL BL MOV BL,AL MOV AH,01H INT 21H ;键盘输入第二个数字 SUB AL,30H ADD AL,BL EXIT: MOV AH,0 MOV BX,AX RET IMPOR ENDP 8. 求AX中数表示的某一年份的日数的子程序 ;子程序名:LEAPY ;程序功能:求AX中数表示的年份的日数 ;入口参数:年份:CX ;出口参数:该年日数:AX ;使用寄存器:DX、BX LEAPY PROC MOV AX,CX ;保存DI到AX MOV DX,0 MOV BX,4 DIV BX CMP DX,0 JNZ DISP3 ;不能整除4,不是闰年 MOV AX, CX MOV BX,100 DIV BX CMP DX,0 JNZ DISP4 ;不能整除100,是闰年 MOV AX, CX MOV BX,400 DIV BX CMP DX,0 JZ DISP4 ;能整除400,是闰年 DISP3: MOV AX,365 MOV BYTE PTR Y,0 ;置非闰年标志 JMP EXIT1 DISP4: MOV AX,366 MOV BYTE PTR Y,1 ;置闰年标志 EXIT1: RET LEAPY ENDP 实验9部分参考程序 1、在数据区中有如下定义,要求首先将有关常量存放到数据区BUF中,再编一个循环程序,使依次以10进制形式显示各变量的值(不要求显示变量名)。 NUM1EQU25*4-50 NUM2EQUNUM1/7 VAR1DB1,2,3,4,5 VAR2DB'12345' NUM4EQUVAR2-VAR1 NUM5EQU0FH BUF DB 7 DUP(?) ;程序1解:以十进制形式显示各数(循环方式) DATA SEGMENT NUM1EQU25*4-50 NUM2EQUNUM1/7 VAR1DB1,2,3,4,5 VAR2DB'12345' NUM4EQUVAR2-VAR1 NUM5EQU0FH BUF DB 7 DUP(?) D1 DB ?,?,?,?,?,? ;根据子程序要求建立显示数据区 DATA ENDS STACK SEGMENT STACK DB 200 DUP(0) STACK ENDS CODE SEGMENT ASSUME DS:DATA,SS:STACK,CS:CODE START:MOV AX,DATA MOV DS,AX MOV SI,OFFSET BUF ;将有关数据放BUF数据区使方便循环求解 MOV ,BYTE PTR NUM1 INC SI MOV ,BYTE PTR NUM2 INC SI MOV AL,VAR1 MOV ,AL INC SI MOV AL,VAR2 MOV ,AL INC SI MOV ,BYTE PTR NUM4 INC SI MOV ,BYTE PTR NUM5 MOV SI,OFFSET BUF ;准备从BUF数据区依次取数显示 MOV DI,OFFSET D1+5 ;根据子程序要求将DI指向显示数据区尾部 MOV BP,6 ;共计显示6个数据 NEXT: MOV AH,0 ;根据子程序要求将欲显示数据取到AX中 MOV AL, ;显示数据为字节类型,而AX为字类型 CALL P1 ;调用显示子程序 INC SI DEC BP ;共显示6个数据,由BP决定循环次数 JNZ NEXT MOV AH,4CH INT 21H ;子程序名:p1 ;功能: 以十进制形式显示任意字 ;输入参数: 显示字在AX中。要求在数据区建5字节的显示数据区, ;要求用DI指向其尾部。 ;输出参数: ;* * * * * * * P1 PROC MOV BX,10 ;准备除以10 CHANGE10: MOV DX,0 ;将除数的高16位(在DX中)清0,DX存放余数 DIV BX ;DX,AX除以BX (BX=10) ADD DL,30H ;余数变为ASCII码值 MOV BYTE PTR ,DL ;存储十进制数 DEC DI ;到上一单元 CMP AX,0 ;是否为0? JNZ CHANGE10 ;不为0转CHANGE10 MOV CX,5 ;准备连续显示5个数 CHANGE11:MOV DL,BYTE PTR ;取出存放在BUF中的十进制数到DL供显示 MOV AH,2 ;显示1个字符 INT 21H INC DI LOOP CHANGE11 RET P1 ENDP CODE ENDS END START 2. 利用子程序结构将八位无符号二进制数转换为十进制数的ASCII码并显示。 DATA SEGMENT BIN DB 11111111B ASC DB 3 DUP(?),$ DATA ENDS STACK SEGMENT STACK DB 200 DUP(0) STACK ENDS CODE SEGMENT ASSUME DS:DATA,SS:STACK,CS:CODE START:MOV AX,DATA ;给数据段寄存器DS赋值 MOV DS,AX MOV AL,BIN MOV BX,OFFSET ASC ADD BX,2 ;指向存放ASCII码值结果的存贮单元末地址 CALL TRANSFORM ;转子程序实现转换 LEA DX,ASC MOV AH,9 INT 21H MOV AH,4CH ;中断返回DOS状态 INT 21H ;* * * * * * * ;子程序名:TRANSFORM ;功能:将八位无符号二进制数转换为十进制数ASCII码 ;入口参数:八位二进制数=AL ; 存放ASCII码值末地址=BX ;出口参数:在ASC开始的存贮单元中 ;* * * * * * * TRANSFORM PROC NEAR PUSH CX PUSH DX MOV CX,3 MOV DL,10 AGAIN:MOV AH,0 DIV DL ADD AH,30H MOV ,AH DEC BX LOOP AGAIN POP DX POP CX RET TRANSFORM ENDP CODE ENDS END START 说明:转换子程序中用到了AX(AH,AL),BX,CX,DX(DH,DL)四个16位的寄存器。为什么进入子程序后,只对CX,DX寄存器作了压栈保护,而对AX,BX 寄存器没有呢?原因在于:AX,BX是用于参数传递目的的两个寄存器,而CX,DX却不是。进入子程序中压栈保护所用的寄存器一般指不用于参数传递目的的寄存器,所以对CX,DX作了压栈保护,而对AX,BX却没有。 另外,此题也可不用除法指令,而采用一连串的相减来实现,思路为:八位二进制数能够减去100的次数,就是转换的十进制数百位;同理,从余下的二进制数中再减去10的次数,便是十进制的十位;最后余下的就是十进制数个位。有兴趣的同学可自己试着实现。 结合上题与本题可以总结子程序的格式,子程序所放的位置,子程序的调用方法。 调用子程序命令为: CALL 子程序以 子程序名 PROC 开始。 例如: TRANSFORM PROC 后面的 NEAR 表示在同一段内,可以省略,否则要用FAR。子程序结尾为: RET 子程序名 ENDP 例如,本子程序结尾: RET TRANSFORM ENDP 每个子程序开始应当给出说明:子程序名、功能、入口参数、出口参数、使用寄存器。既便于自己理解,也方便之后其他程序调用。使用寄存器只列举在本程序中使用了但未在子程序中保护且不是入口参数和出口参数中声明了的寄存器。 子程序用CALL命令调用,格式: CALL 子程序名 子程序不能在代码中随意放,初学建议放在MOV AH,4CH 和 INT 21H 这二句之后。 3. 用子程序形式求解实验7第3题:在内存的源数据区SOURCE处有若干个ASCII码字符,要求将其中的英文大写字母变换为小写字母,其它字符不变换,并存放到结果数据区DEST处。 分析:英文大写字母AZ,ASCII码值为41H5AH。相应的小写字母为az,ASCII码值为61H7AH。英文大写字母要转换为相应的小写字母只要ASCII码值加20H即可。 例如:B─b 42H+20H=62H 我们将转换这一过程用子程序TRANBL来实现,参数传递借助存贮单元,其算法流程图如右图所示。 完整程序如下所示: DATA SEGMENT SOURCE DB 'BEIjin2008OLYMPIC' COUNT EQU $-SOURCE ;字符个数 DEST DB COUNT DUP(?) DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX CALL TRANBL MOV AH,4CH INT 21H ;* * * * * * * ;子程序名:TRANBL ;功能:大写字母转换为小写字母 ;输入参数:数据区SOURCE处,字符个数由COUNT指明 ;输出参数: 输出数在数据区DEST处 ;* * * * * * * TRANBL PROC NEAR PUSH AX PUSH CX PUSH SI PUSH DI MOV SI, OFFSET SOURCE MOV DI, OFFSET DEST MOV CX,COUNT AGAIN:MOV AL, CMP AL,41H ;与大写字母A比较 JB NEXT CMP AL,5AH ;与大写字母Z比较 JA NEXT ADD AL,20H ;转换 NEXT:MOV ,AL INC SI INC DI LOOP AGAIN POP DI POP SI POP CX POP AX RET TRANBL ENDP CODE ENDS END START 6. 求将一个16位二进制数转换为任意P(0到19)进制数,P从键盘输入并显示(超过9的数字按:10用A,11用B,,19用I表示)。 分析:在前面例子中已经给出了16位二进制数转换为十进制、十六进制的例子,方法都是依次除进制数、取余、倒写。转换为任意P进制数的问题,只是将这些例题中的除数要更换为P的具体值。可以将这些转换程序改写成子程序,子程序中要用到寄存器DI、AX,使用寄存器不多,故设计P从主程序经BX带入、二进制数从主程序经SI带入。为具有实用价值,本题所涉及的P值及二进制数均从键盘输入,输入的都是ASCII码,需要变成二进制数,该工作分别设计子程序完成。 程序设计如下: DATA SEGMENT CHAR_BUF DB 6 ;缓冲区最大长度 DB ? ;实际输入字符个数 DB 6 DUP(0) ;输入缓冲区 BUF DB 17 DUP(0) ;输出缓冲区 CLEW1 DB 'PLEASE INPUT ALGORI X(0....65535) :', '$' ;提示信息1 CLEW2 DB 0DH,0AH,'PLEASE INPUT CARRY P(0....19) :', '$' ;提示信息2 ENTER1 DB 0DH,0AH, '$' ;回车换行 DATA ENDS STACK SEGMENT STACK DB 200 DUP(?) STACK ENDS CODE SEGMENT ASSUME DS:DATA,CS:CODE,SS:STACK START:MOV AX,DATA MOV DS,AX MOV DX,OFFSET CLEW1 ;提示信息1 MOV AH,9 INT 21H CALL IMPOR1 ;输入二进制数子程序 MOV DX,OFFSET CLEW2 ;提示信息2 MOV AH,9 INT 21H CALL IMPOR2 ;输入进制数P子程序 MOV DX,OFFSET ENTER1 ;回车换行 MOV AH,9 INT 21H MOV DI, OFFSET BUF ;根据VERSIO入口要求使指针DI指向BUF缓冲区 ADD DI,17 ;假定BUF从0起准备17个单元,DI指向BUF尾 MOV BYTE PTR ,$ ; 所有余数的最后加$ CALL VERSIO ;转换并显示子程序 MOV AH,4CH INT 21H ;子程序名:IMPOR1 ;程序功能:从键盘输入至多5个十进制数字变成二进制数(0到65535),回车表示输完 ;入口参数:缓冲区首址:CHAR_BUF ;出口参数: 从键盘输入的数:SI ;使用寄存器:DI,DX,BX,CX,AX IMPOR1 PROC NEAR INPUT: MOV DX,OFFSET CHAR_BUF MOV AH,0AH INT 21H ;键盘输入字符串 MOV DI,OFFSET CHAR_BUF MOV CL, ;取实际输入串长度 MOV CH,0 MOV AX,0 ;准备存放结果 MOV BX,10 ;乘10的乘数 MOV DH,0 ;清DX高8位 CHANGE: MUL BX ;(AX)乘10 MOV DL, ;取一个字符 SUB DL,30H ;变成数字 ADD AX,DX INC DI LOOP CHANGE MOV SI,AX ;带出结果 RET IMPOR1 ENDP ;子程序名:IMPOR2 ;程序功能:从键盘输入至多二个十进制数字变成进制数P(219) ;入口参数: ;出口参数: 进制数P:BX ;使用寄存器:AX IMPOR2 PROC NEAR MOV AH,01H INT 21H ;键盘输入1个字符,不考虑输入错 SUB AL,30H CMP AL,1 ;如果第1个字符输入大于1,表示只1位 JA EXIT MOV BL,10 MUL BL MOV BL,AL MOV AH,01H INT 21H ;键盘输入第二个数字 SUB AL,30H ADD AL,BL EXIT: MOV AH,0 MOV BX,AX RET IMPOR2 ENDP ;子程序名:VERSIO ;程序功能:将16 位二进制数转换为P进制数并显示 ;入口参数:数组BUF首址: DI,进制数P:BX,存放二进制数:SI ;出口参数: ;使用寄存器:AX VERSIO PROC NEAR MOV AX,SI CHANGE1: DEC DI ;指针向前移 DIV BL ;(AX)除以P余数在AH中 ADD AH,30H ;余数变为对应的ASCII码值 CMP AH,39H ;是否是A-F JBE NEXT ADD AH,7 ;如果是A-F,再加7 NEXT: MOV BYTE PTR ,AH ;保存转换后的十六进制数结果 MOV AH,0 CMP AL,0 ;判断商是否为0? JNZ CHANGE1 ;不为0转CHANGE1 MOV DX,DI MOV AH,9 INT 21H RET VERSIO ENDP CODE ENDS END START 7. 求一个小于65535的整数N的因数分解,即将一个整数分解成质数的乘积。 分析:因数分解的方法是从I=2起,看能否整除N,如果能,则I为一个质数,记下整除后的数代换N并继续整除到不能整除为止。再将I加1后继续,,直到I大于被除数为止。 ;设数据区如下,求分解为质数放在PRIMEN中并显示。 DATA SEGMENT M1 DW 10920 M2 DW 0 PRIMEN DW 10 DUP(0) M DB 0 d db 5 dup(0) DATA ENDS STACK SEGMENT STACK DB 200 DUP(?) STACK ENDS CODE SEGMENT ASSUME DS:DATA,CS:CODE,SS:STACK START:MOV AX,DATA MOV DS,AX CALL PRIME ;转分解质数子程序 LEA DI,D+5 ;指向显示数据区尾地址 LEA SI,PRIMEN ;指向质数数据区首地址 MOV CL,M ;欲显示的质数个数 MOV CH,0 LOOP1:MOV AX, ;取显示数据 CALL P1 ADD SI,2 LOOP LOOP1 MOV AH,4CH INT 21H ;子程序名:PRIME ;程序功能:将字数据分解为质数 ;入口参数:字数据:变量M1 ;出口参数: 质数数组:PRIMEN ; 数组元素个数:M ;使用寄存器:AX PRIME PROC MOV DI,OFFSET PRIMEN MOV AX,M1 MOV M2,AX MOV CL,0 DISP1: MOV BX,2 ;从2开始分析质数 DISP2: MOV AX,M2 MOV DX,0 DIV BX CMP DX,0 ;余数是否为0? JNE DISP4 MOV ,BX ;保存一个质数 ADD DI,2 ;准备存放下一个质数 MOV M2,AX INC CL DISP3: MOV DX,0 DIV BX CMP DX,0 ;继续取出同一个质数不再保存 JNE DISP4 MOV M2,AX JMP DISP3 DISP4: CMP BX,M2 JA EXIT INC BX JMP DISP2 EXIT: MOV M,CL RET PRIME ENDP ;子程序名:p1 ;功能: 以十进制形式显示任意字 ;输入参数: 显示字在AX中。要求在数据区建5字节的显示数据区, ;要求用DI指向其尾部。 ;输出参数: ;* * * * * * * P1 PROC PUSH BX PUSH DX PUSH DI PUSH CX MOV BX,10 ;准备除以10 CHANGE10: MOV DX,0 ;将除数的高16位(在DX中)清0,DX存放余数 DIV BX ;DX,AX除以BX (BX=10) ADD DL,30H ;余数变为ASCII码值 MOV BYTE PTR ,DL ;存储十进制数 DEC DI ;到上一单元 CMP AX,0 ;是否为0? JNZ CHANGE10 ;不为0转CHANGE10 MOV CX,5 ;准备连续显示5个数 CHANGE11:MOV DL,BYTE PTR ;取出存放在BUF中的十进制数到DL供显示 MOV AH,2 ;显示1个字符 INT 21H INC DI LOOP CHANGE11 POP CX POP DI POP DX POP BX RET P1 ENDP CODE ENDS END START 8. 计算:X的平方根与有的平方根的和 其中x、y为整型数据,分别存放在XBUF和YBUF单元中,所得结果f存放在FBUF中。要求将FBUF中数据在屏幕上显示。 分析:求一个整数平方根可以通过将该整数依次减去1、3、5、7(n-1)的奇数,所够减的次数即为平方根值。 例如求16的平方根时可这样进行: 16-1=15 够减1次 15-3=12 够减2次 12-5=7 够减3次 7-7=0 够减4次 所以16=4 求平方根的过程我们用子程序SQROOT来实现,参数的传递借助堆栈。求平方根子程序算法流程图如图所示。 DATA SEGMENT XBUF DW 81 YBUF DW 100 FBUF DW ? DATA ENDS STACK SEGMENT TOP DW 20 DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK START:MOV AX,DATA ;给DS赋值 MOV DS,AX MOV SI,XBUF CALL SQROOT MOV AX,SI MOV SI,YBUF CALL SQROOT ADD SI,AX CALL DISPLAY16 MOV AH,4CH INT 21H ;* * * * * * * ;子程序名:SQROOT ;功能:求平方根运算 ;输入参数:SI ;输出参数:SI ;* * * * * * * SQROOT PROC NEAR PUSH AX PUSH BX PUSH CX MOV AX,SI ;取被开方数 SUB CX,CX ;CX置0 AGAIN:MOV BX,CX ;下面三条指令使BX=2*CX+1 ADD BX,BX INC BX SUB AX,BX JC OVER ;不够减转OVER INC CX JMP AGAIN OVER:MOV SI,CX ;平方根放回原堆栈区 POP CX POP BX POP AX RET SQROOT ENDP ;子程序名:DISPLAY16 ;功能:以移位方式显示16进制数 ;占用寄存器:BX,CL,AX,DX ;输入参数:要显示数据在SI中 ;输出参数:无 DISPLAY16 PROC MOV BX,4 ;每个字显示4个16进制字符 CHANGE10: MOV CL,4 ;准备左移4位(除以16) ROL SI,CL ;SI循环移4位 MOV DX,SI ;转存到DX AND DX,0FH ;清高12位 ADD DL,30H ;一个16进制数变为ASCII码值 CMP DL,3AH ;是否小于10? JB CHANGE12 ;如果小于10转显示 ADD DL,7 ;否则为A到F之间数,加7 CHANGE12: MOV AH,2 ;显示1个字符 INT 21H DEC BX ;处理下一个字符 CMP BX,0 ;是否为0? JNZ CHANGE10 ;不为0转CHANGE10 RET DISPLAY16 ENDP CODE ENDS END START 本题如果采用堆栈传递参数的程序如下所示,请注意堆栈的变化。 DATA SEGMENT XBUF DW 81 YBUF DW 100 FBUF DW ? DATA ENDS STACK SEGMENT TOP DW 20 DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK START:MOV AX,DATA ;给DS赋值 MOV DS,AX MOV AX,STACK ;给SS赋值 MOV SS,AX MOV SP,SIZE TOP ;确定SP的指向位置 MOV AX,XBUF ;取被开方数X PUSH AX ;压入堆栈 CALL SQROOT POP AX ;取X平反根暂存AX中 MOV DX,YBUF ;取被开方数Y PUSH DX ;压入堆栈 CALL SQROOT POP DX ;取Y平反根存入DX中 ADD AX ,DX ; + MOV FBUF,AX ;送入FBUF单元 MOV SI,FBUF CALL DISPLAY16 MOV AH,4CH INT 21H ;* * * * * * * ;子程序名:SQROOT ;功能:求平方根运算 ;输入参数:压入堆栈区 ;输出参数:位于堆栈区 ;* * * * * * * SQROOT PROC NEAR PUSH BP MOV BP,SP ;定位 PUSH AX PUSH BX PUSH CX MOV AX, ;取被开方数 SUB CX,CX ;CX置0 AGAIN:MOV BX,CX ;下面三条指令使BX=2*CX+1 ADD BX,BX INC BX SUB AX,BX JC OVER ;不够减转OVER INC CX JMP AGAIN OVER:MOV ,CX ;平方根放回原堆栈区 POP CX POP BX POP AX POP BP RET SQROOT ENDP ;子程序名:DISPLAY16 ;功能:以移位方式显示16进制数 ;占用寄存器:BX,CL,AX,DX ;输入参数:要显示数据在SI中 ;输出参数:无 DISPLAY16 PROC MOV BX,4 ;每个字显示4个16进制字符 CHANGE10: MOV CL,4 ;准备左移4位(除以16) ROL SI,CL ;SI循环移4位 MOV DX,SI ;转存到DX AND DX,0FH ;清高12位 ADD DL,30H ;一个16进制数变为ASCII码值 CMP DL,3AH ;是否小于10? JB CHANGE12 ;如果小于10转显示 ADD DL,7 ;否则为A到F之间数,加7 CHANGE12: MOV AH,2 ;显示1个字符 INT 21H DEC BX ;处理下一个字符 CMP BX,0 ;是否为0? JNZ CHANGE10 ;不为0转CHANGE10 RET DISPLAY16 ENDP CODE ENDS END START 思考:请编写求解一元二次方程AX2+BX+C=0的程序。
个人分类: 生活点滴|10129 次阅读|3 个评论
汇编语言实验手册详细目录
热度 1 求新 2009-2-16 12:27
实验手册详细目录 实验 1 认识性实验 1. 显示数据区中的一个字符 2. 显示数据区中的一个十进制数字 3.10 以内的加法程序并显示结果 4. 以二进制形式显示一个字符的 ASCII 码 实验 2 数据转换实验 1. 二进制数转换为十进制数。将 D0 起字单元中存放的 16 位二进制数转换为十进制数 , 并将其 ASCII 码存入 DI 所指向的缓冲区 BUF 中 , 最后显示出来。 2.ASCII 码表示的十进制数转换为二进制数并显示。将 SI 指向的缓冲区 BUF 中保存的五位 ASCII 码十进制数( 0-65535 )转换成对应的二进制数并存放在 DX 中 , 再以二进制形式显示。 3. 二进制数到十六进制数的转换 4.ASCII 码表示的十六进制数到二进制数的转换。从键盘输入四位十六进制数 , 将其转换十六位二进制数 , 并保存在 DX 寄存器中 , 再显示。 实验 3 简单数据运算程序设计 1. 求计算二个字类型无符号数的和并以十进制形式显示。设和的大小不超过 16 位二进制数。 2. 如果要将二进制数的和以十六进制形式显示,求修改以下实验程序,补充数据区设计,使能上机实现。 3. 检查 4 个输入的数 , 如果是 16 进制数字就保留并显示 , 否则停止输入并退出。 4. 求一个数 X 的 9-X 并显示。 5. 求解二元一次方程组: A1X+B1Y=C1 A2X+B2Y=C2 实验 4 涉及压缩 BCD 码数据的转换程序及 DEBUG 练习 1. 按如下步骤操作,了解 DEBUG 命令及其使用方法。 2. 在编译与连接生成执行程序之后利用 DEBUG 调试该程序,了解不同变量数据存储情况,了解变量的三种含义及用法,了解加法、乘法运算方法及对标志位的影响。 3. 检查下面那些指令是错误的 , 说明原因并改正。 4. 十进制数的 ASCII 码转换为压缩型 BCD 码 5. 压缩 BCD 码转换为十进制数的 ASCII 码 6. 二进制数转换为压缩 BCD 码 7. 压缩 BCD 码转换为二进制数 实验 5 算术运算程序设计 1. 单步运行以下 8 位 2 进制数加法: 88H+0CH ; 0CEH+ 0C 4H ; 0CEH+84H 与 16 位 2 进制数加法: 9588H+720CH ; 9588H+0B284H 运算程序,对每次运算分析其对标志位的影响。记录实验结果,并与分析结果比较。 2. 分析以下程序功能是什么?分析其每一次算术运算对标志位的影响。记录实验结果,并与分析结果比较。 3. 已知数据存储区如下所示, DN1 与 DN2 均为双字,自编程序段:计算 DN1+DN2 ,将结果放到 DSUM 中。上机验证,报告其中各进行算术运算后对标志位影响的情况。 4. 修改上面的程序,将运行结果以 16 进制形式在屏幕上显示。 5. 按下列要求编写指令序列上机实现 1 )清除 DH 中最低 3 位而不改变其他位,结果存入 BH 。 2 )将 DL 中最高 3 位置 1 而不改变其他位。 3 )将 AX 中 0~3 位置 1 、 7~9 位取反、其他位清 0 。 4 )检查 BX 中第 2 、 5 、 9 位是否至少有 1 位是 1 。 5 )检查 CX 中第 1 、 6 、 11 位是否同时为 1 。 6 )检查 BX 中第 0 、 2 、 9 、 13 位是否至少有 1 位是 0 。 7 )检查 DX 中第 1 、 4 、 11 、 14 位是否同时是 0 。 6. 编写指令序列实现: 1 )右移 DL 3 位,并将 0 移入最高位。 2 )将 AL 左移一位,将 0 移入最低位。 3 ) DX 右移 6 位且保持正负特性不变。 4 )将 AL 中压缩 BCD 码变成 AX 中的非压缩 BCD 码。 7 .设 A,B,C 为 8 位带符号数 ,D 为 16 位带符号数,计算算术表达式 ((A*B-32486H)+C)/D 的值,结果中的商存放到( AX )寄存器中(假设 D 的值足够大),余数存放到( DX )寄存器中。 附:供参考程序段: 1. 双字加法程序段 2. 16 进制形式在屏幕上显示二进制数据程序段 3. 清除 DH 中最低 3 位而不改变其他位,结果存入 BH 。 4. 将 DL 中最高 3 位置 1 而不改变其他位,结果存入 BH 。 5. 将 AX 中 0~3 位置 1 、 7~9 位取反、其他位清 0 。 6. 检查 BX 中第 2 、 5 、 9 位是否至少有 1 位是 1 。 7. 检查 CX 中第 1 、 6 、 11 位是否同时为 1 。 8. 检查 BX 中第 0 、 2 、 9 、 13 位是否至少有 1 位是 0 。 9. 检查 DX 中第 1 、 4 、 11 、 14 位是否同时是 0 。 10. 右移 DL 3 位,并将 0 移入最高位。 11. 将 AL 左移一位,将 0 移入最低位。 12. DX 右移 6 位且保持正负特性不变。 13. 将 AL 中压缩 BCD 码变成 AX 中的非压缩 BCD 码。 实验 6 自编有关双精度数据运算及逻辑运算、移位程序 1. 设数据区有双精度数据 A 、 B 定义例如: A DD 2A 3D0B2CH B DD 2573ADEH 求自编程序 , 计算 A 与 B 的和与差 , 并用二进制形式分别显示。 2. 设数据区有双精度数据 A 、 B 定义如上 , 求自编程序 , 计算 A 与 B 的积 , 并用十六进制形式显示。 3. 自编程序,任意设 AX 的值,求将其中 1 、 3 、 5 位清 0 , 2 、 4 、 9 位置 1 , 6 、 7 位求反。分别用二进制形式显示原数据及处理后的数据。 4. 自编程序,任意设 4 位压缩 BCD 码数据放到 AX 中,求用移位方法及 2 号 DOS 中断显示其值。 5. 设数据区有压缩 BCD 码数据 A 、 B 定义例如: A DW 2937H B DW 877H 求自编程序 , 计算 A 与 B 的和 , 并用十进制形式显示。 6. 设数据区有非压缩 BCD 码数据 A 、 B 定义例如: A DW 0907H B DW 0807H 求自编程序 , 计算 A 与 B 的和 , 并用十进制形式显示。 7. 设计求两个二位压缩 BCD 码的乘积(用压缩 BCD 码表示)的程序。(例如 86H*39H ,结果为 3354H ) 8. 设计求四位压缩 BCD 码除以二位压缩 BCD 码表示的程序。(例如 8390H 29H ,结果为 289H 余 9 ) 9. 设数据区有双精度数据 A 、字类型数据 B , 求自编程序 , 计算 A/B 的商与余数,各用十进制形式显示。 10. 设数据区有双精度数据 A 、 B , 求自编程序 , 计算 A/B 的商与余数。,各用十进制形式显示。 供参考的程序段: (1) 以二进制形式显示任意字符的 ASCII 码(要求在数据区设置 A , DB 类型) (2) 二进制数转换为十进制数。 要求在数据区设置 BUF DB 10 DUP(0) 和 D0 ,例如 D0 DW 1234 (3) 二进制数转换为压缩型 BCD 码,要求在数据区有 ASC_BUF 数据, DB 类型,共 16 个单元,要转换的数据要放到 DX 中。 (4) 压缩型 BCD 码转换为二进制数,要转换的数据要放到 DX 中。 (5) 压缩型 BCD 码的加法运算 (6) 单字节压缩 BCD 码的减法运算 (7) 单字压缩 BCD 码的减法运算 ; 已知 AX = 1234H 、 BX = 4612H, 计算 1234 - 4612 的差 (8) 非压缩 BCD 码的加法运算 (9) 非压缩 BCD 码的减法运算 (10) 一位非压缩 BCD 码的乘法运算 (11) 非压缩 BCD 码的除法运算 (12) 两个二位压缩 BCD 码的乘积(用压缩 BCD 码表示)。 (13) 设计求四位压缩 BCD 码除以二位压缩 BCD 码表示的程序。(例如 8390H 29H ,结果为 289H 余 9 ) (14) 双字加法 (15) 双字除单字除法(设被除数在 DX AX 中,除数在 BX 中,在数据区中准备字类型 3 个字数据区 C : C DW ?,?,? ) (16) 双精度数减法 实验 7 循环程序设计练习 1. 求利用 2 号中断接受从键盘输入的最多 4 个 16 进制数字组成一个 16 进制数,并依次用十六进制、十进制显示的程序。 2. 接上题,求将字变量 BUF 的值乘以上述 16 进制数,再用十六进制数显示的程序。 3. 在内存的源数据区 SOURCE 处有若干个 ASCII 码字符,要求将其中的英文大写字母转换为小写字母,其它字符不转换,并存放到结果数据区 DEST 处。已知数据区如下。 DATA SEGMENT SOURCE DB BEIjin2008OLYMPIC COUNT EQU $-SOURCE ;字符个数 DEST DB COUNT DUP(?) DATA ENDS 4. 修改上述程序:将输入到数据区 DEST 处的字符串在屏幕上显示出来。 5. 将以下参考程序段中第 3 到 9 题补充完整再上机验证。 供参考的程序段: (1) 二进制数转换为十六进制数显示。 (2)ASCII 码表示的十进制数转换为二进制数并显示。要求在数据区设置要求显示的 BUF 数据, DB 类型 (3) 以移位方式显示 16 进制数 ( 要求在数据区设置用来变十六进制数的数 D0 ,例如 D0 DW 1234h) (4)ASCII 码表示的十六进制数到二进制数的转换 (5) 十进制数的 ASCII 码转换为压缩型 BCD 码。要求在数据区有 ASC_BUF 、 BCDBUF 二个数据集,由若干个十进制数的 ASCII 码字符组成,要定义其长度放到 COUNT 中。 (6)BCD 码转换为十进制数的 ASCII 码,要求在数据区有 ASC_BUF 数据, DB 类型,共 3 个数据。 (7) 双字除 10 取余求变 10 进制数(设双字在 DX AX 中,除数 10 在 BX 中,在数据区中准备字节类型 10 个字数据区 D : D DB 10 DUP(?) ) (8) 利用 10 号 DOS 中断输入 1 到 10 个 10 进制数,求变成 2 进制数存到 DX AX 中。 (9) 在数据区 SOURCE 处有 20 个字节无符号数,计算其累加和。 实验 8 用循环程序设计方法解串操作问题实验 1 、如果有字节变量 X ,存放一个字母,在 DEST 数据区存放有一字符串,求在该字符串中查找该字母,如果找到,显示该字母及该字母所在位置的偏移地址。 2 、接上题,如果有字变量 X ,存放二个字母,求在 DEST 数据区查找该二字母,如果找到,显示该字母所在位置的偏移地址。 (附实现程序) 3 、在数据区 SOURCE 处有 20 个字节无符号数,计算其累加和,结果存放在符号地址 RESULT 字单元处并在屏幕上显示。 (附实现程序) 4 、 从键盘输入一个字符串,然后在下一行以相反的顺序显示出来。 (附实现程序) 5 、有一个长度 COUNT 的字节类型的串 BUF ,用程序对这个串进行从小到大的排序,要求分别用气泡法、选择法、插入法完成。 (附实现程序) 6 、假设待匹配的元素存放在 KEY 单元中,且 LIST 表为一个所有元素已按从小到大顺序排列的有序表。编制程序实现在 LIST 表中用折半查找法查找是否有与 KEY 单元中的内容相匹配的元素,若查找到将其在表中的地址存入 ADR 单元;若未找到则将 ADR 单元置全 1 。 (附实现程序) 7 、比较 A 、 B 两个串的大小,如果 A 串大,显示 A ;如果 B 串大,显示 B ;否则,显示 E 。 实验 9 利用子程序实现数据变换与数据处理的程序设计 1. 在数据区中有如下定义 , 要求首先将有关常量存放到数据区 BUF 中,再编一个循环程序 , 使依次以 10 进制形式显示各变量的值(不要求显示变量名)。要求将 10 进制形式显示程序段利用子程序进行设计。 (附实现程序) NUM1 EQU 25*4-50 NUM2 EQU NUM1/7 VAR1 DB 1,2,3,4,5 VAR2 DB '12345' NUM4 EQU VAR2-VAR1 NUM5 EQU 0FH BUF DB 7 DUP(?) 2. 利用子程序结构将八位无符号二进制数转换为十进制数的 ASCII 码并显示。 (附实现程序) 3. 用子程序形式求解实验 7 第 3 题:在内存的源数据区 SOURCE 处有若干个 ASCII 码字符,要求将其中的英文大写字母变换为小写字母,其它字符不变换,并存放到结果数据区 DEST 处。 (附实现程序) 4. 修改上述程序:利用 9 号系统功能调用将输入到数据区 DEST 处的字符串在屏幕上显示出来。 5. 用子程序形式求解实验 8 第 3 题:在数据区 SOURCE 处有 20 个字节无符号数,计算其累加和,结果存放在符号地址 RESULT 字单元处。要求以 16 进制形式在屏幕上显示结果。 6. 求将一个 16 位二进制数转换为任意 P ( 0 到 19 )进制数, P 从键盘输入并显示(超过 9 的数字按: 10 用 A , 11 用 B ,, 19 用 I 表示)。 (附实现程序) 7. 求一个小于 65535 的整数 N 的因数分解,即将一个整数分解成质数的乘积。 分析:因数分解的方法是从 I=2 起,看能否整除 N ,如果能,则 I 为一个质数,记下整除后的数代换 N 并继续整除到不能整除为止。再将 I 加 1 后继续,,直到 I 大于被除数为止。 (附实现程序) 8. 计算: f= + 其中 x 、 y 为整型数据,分别存放在 XBUF 和 YBUF 单元中,所得结果 f 存放在 FBUF 中。要求将 FBUF 中数据在屏幕上显示。 (附实现程序) 实验 10 利用子程序进行串处理及有关日期的程序设计 1. 要求自行设定二个字类型的串 STRING1 与 STRING2 的内容,用程序对这二个串进行比较,如果相等, 0 送 BX ,否则, 0FFFFH 送 BX 。设串长为 COUNT 。最后分别以 16 进制形式显示 BX 、 STRING1 与 STRING2 的内容。 2. 已知程序段如下 , 将它补充完整 , 使能将结果( BX 的值)以 16 进制形式在屏幕上显示 , 根据显示情况分析说明其功能是什么?要求将 16 进制显示程序段利用子程序进行设计。 (附实现程序) 3. 对程序段进行补充设计,要求对设计加详细注释。要求自行设定一个长度 COUNT 的字节类型的串 STRING 的内容,用程序对这个串进行搜索,如果搜索到字节类型数据 A ,显示当前位置(字长)。 STRING 、 COUNT 、 A 的内容自行设计。 4. 在一个串中查找一个字符,显示查到该字符的次数。 (附实现程序) 5. 在一个串中查找一个字符,显示所有查到位置的地址。如果没有欲查字符,显示 -1 。 (附实现程序) 6 .在一个串中查找另一串,如果找到,将查到串的首地址存到 DI 中。 (附实现程序) 7 .求编写显示系统的当前日期和时间的程序。要求程序运行时显示的信息格式为: Current date is 10-30-2008 . Current time is 10:23:26.12 (附实现程序) 8. 设计一个万年历程序。已知 2008 年 1 月 1 日 为星期二,求 2008 年之后 21 世纪的某年某月某日是星期几?不考虑输入错误。 (附实现程序) 实验 11 宏汇编程序设计 1. 求三个字节变量 x, y, Z 的值的平均值,并显示其整数部分。 (附实现程序) 2. 编一个菜单程序,在屏幕上显示各菜单项提示,当用户选择并输入 1 或 2 时调用相应宏程序 MACRO1 或 MACRO2 。 MACRO1 将字符串中小写字变大写。 MACRO2 将字符串中大写字变小写。 (附实现程序) 3. 设计从键盘输入 A 、 B 二个数,求其和并显示的程序( A 与 B 的和不大于 65535 )。要求将其中键盘输入、求和、显示的程序分别用宏程序实现。 (附实现程序) 4. 求建立宏库 MACRO1.lib : 5. 将实验 6 、 7 、 8 中供参考的程序段改造成宏程序,并添加到宏库 MACRO1.lib 中去。要求宏体开始处将其中与输入、输出参数无关的所以涉及的寄存器中数据压入堆栈保护。 实验 12 递归程序与浮点运算 1. 利用递归程序求数组最大值。 (附实现程序) 2. 有二个正整数 M 、 N ( M=N ),求它们的最大公约数,放到 DIVISO 中。 (附实现程序) 3. 斐波那契的兔子问题:假定小兔子一个月后可以长成大兔子,二个月及之后的大兔子每个月都会生出一对小兔子。如果年初养了一对小兔子,问到年底时将有多少对兔子 ? (附实现程序) 4. 求 Hanoi 塔的递归程序 (附实现程序) 5. 假设有两个浮点数,其中被加数在双字变量 BUF1 中,加数在双字变量 BUF2 中。试计算其和并置于 BUF3 中。 (附实现程序) 实验 13 BIOS 功能调用程序设计 1. 读键盘,把用户所按键显示出来,若用户按下 SHIFT 键,则结束运行。写出完成该功能的程序。 (附实现程序) 2. 单色文本显示方式举例。在屏幕上的第 9 行第 16 列的位置显示一个黑桃(对应的 ASCII 码为 06H ),要求黑桃为黑色且闪动,背景选为白色(即白底黑字)。 (附实现程序) 3. 彩色文本显示方式举例。以蓝色为背景,在 10 行 20 23 列显示四个梅花( ASCII 码为 5 ) , 梅花的颜色分别选为红、绿、黄和黑色。 (附实现程序) 4. 彩色图形显示方式举例。在屏幕中间显示彩色的梯子。 (附实现程序) 5 .在数据区设置变量 X ,其值为 20 到 40 之间数,求在屏幕中心显示一个正方形,边长等于 X 。 6. 如果已知二个点的坐标( X1 , Y1 )与( X2 , Y2 ),画出连接这两点的连线,假设 X2X1 。 (附实现程序) 7. 在屏幕上设置鼠标位置。 (附实现程序) 8. 已知汉字字模如图所示,求显示该二汉字。如果欲将其长宽均放大一倍,求显示。如果长宽缩小一半,求显示。说明出现的问题。 (附显示汉字实现程序) 实验 14 有关声音的程序设计 1. 编写通用发声子程序,它能利用定时器发出指定频率的声音。在 DI 中存放指定的发声频率,利用 BX 控制延时时间的计数初始值 (附实现程序) 2. 试编写发声程序,利用定时器发出音乐 1234567 ⅰ。 (附实现程序) 3. 设计一个虚拟钢琴程序,手按键盘,根据键盘输入的数据进行演奏。 (附实现程序) 4 .编写一个游戏程序,实现如下功能:( 1 )首先用蓝色清屏。( 2 ) 在在屏幕中央显示由字符串 -============# 组成的黄色的小蛇, # 为蛇头, - 为蛇尾。( 3 ) 按下方向键可以控制上述小蛇按蛇行方式在屏幕上行走。 (附实现程序) 实验 15 文件处理 1. 利用顺序存取方式建立一个文件 FILE1.DAT ,再将预先存放在数据区中的数据顺序写到文件中。 (附实现程序) 2. 从文件 FILE1.DAT 读入一条记录再写入到文件 FILE2.DAT 中。 (附实现程序) 3. 利用随机存取方式建立一个文件 FILE1.DAT ,从键盘输入数据存放在数据区中,再将存放在数据区中的数据写到文件中。 (附实现程序) 4. 求编程序:从键盘输入 20H 个字符到利用扩充文件管理方式建立的文件 FILE1.DAT 。 (附实现程序) 5. 求编程序:将数据从文件 FILE1.DAT 读取 10H 个字符到文件 FILE2.DAT 中。 (附实现程序) 6. 利用扩充文件管理方式从文件 FILE1.DAT 中读出全部内容,再转存到文件 FILE2.DAT 的原内容的后面。 (附实现程序) 7. 从文件 FILE1.DAT 中读出从 N1 起 , 长度为 N2 的字符串 , 在屏幕上显示。 N1 , N2 为十进制数。 (附实现程序) 8. 读出文件 FILE1.DAT 的内容,在屏幕上显示。每次读 1200 个字符,文件最大 64K 。 (附实现程序) 9. 设数据区中有定义: DATA1 DB 100H DUP(0) ; FNAME DB 'FILE1.DAT' ; FCB1 DB 100H DUP(0) 。求利用顺序或随机存取方式建立一个文件 FILE1.DAT ,再将数据区 DATA 中的数据写到文件中。以下给出程序段,请补充完整并上机验证。 10. 查出 C 盘上所有文件名并写入到文件 FilEl.DAT 中。 (附实现程序) 11. 读出 D 盘目录 MASM5 中的文件 FILE1.DAT 的日期与时间。 (附实现程序) 12. 求显示某文件夹下文件目录名称。 (附实现程序) 实验 16 结构类型及其他程序设计 1. 设成绩表数据按如下结构组织。所有数据按左靠齐存放。求填写各人分数排名。 学号(长度: 5 ) 姓名(长度: 8 ) 分数(长度: 1 ) 排名(长度: 2 ) (附实现程序) 2. 设成绩表数据按如下结构组织。所有数据按左靠齐存放,求按分数排名对记录排序。 ; 学号(长度: 5 ) 姓名(长度: 10 ) 分数(长度: 1 ) (附实现程序) 3. 设成绩表数据结构与第二题相同。求录入一条新记录到所有记录之后的程序。 (附实现程序) 4. 设成绩表数据结构与第二题相同。求根据姓名查找并删除所查到记录的程序。 (附实现程序) 5. 已知数据表结构如表所示,数据从文件 FILE1.DBF 起始位置开始,均以 ASCII 码形式存放,每列中的数据长度相同,见标在表中的数据。各行的长度也为定值,等于各列长度之和。求设计依次显示表中各人年龄的程序,年龄以二位 ASCII 码形式存放。(附实现程序) 数据表结构 序号(长度: 4 ) 姓名(长度: 8 ) 年龄(长度: 2 ) 1 Chen 23 2 Wang 25 6. 已知数据表结构及文件结构与上题相同,求编修改程序:根据键盘输入的人的姓名查找行(记录),再将键盘输入的数据去修改表中年龄数据。 (附实现程序) 7. 计算 B/A 的值。利用条件汇编判断 A 是否为 0 后再处理。(附实现程序) 8. 编写在内存中驻留时钟显示的程序 (附实现程序) 9. 编写驻留内存显示键盘缓冲区数据程序 (附实现程序) 附录 输入输出程序设计 1 、已知 8279 与 LED 显示器及小键盘连接如图所示, 8279 的片选 CS79 连至译码处的 210~217 。 8279 工作方式为:左边输入,八位显示,外部译码,双键互锁。求设计程序:( 1 )将键盘接收到的字符送到计算机的显示器上显示。( 2 )在数据区定义二个压缩 BCD 码,求和后在 LED 上显示。 2 、某实验系统将 8255 的片选 CS55 连至译码处的 200~207 。 8255 的 PA 口分接 4 个四个双色灯按要求发光。双色灯接法如下图所示。双色 LED 是由一个红色 LED 管芯和一个绿色 LED 管信封装在一起,公用负端。当红色正端加高电平,绿色正端加低电平时,红灯亮;红色正端加低电平,绿色正端加高电平时,绿灯亮;两端都加高电平时,黄灯亮。求设计程序:状态 1 为:南绿东红北黄西黄灯;延时后状态 2 :南黄东绿北红西黄灯;再延时后状态 3 :南黄东黄北绿西红灯;再延时后状态 4 :南红东黄北黄西绿灯;再反复循环至状态 1 。 3 、编写一个程序完成两台计算机通过 COM2 端口进行串行数据通信。要求从一台计算机上输入字符传送到另一台计算机上,若按下 ESC 键,则退出程序。 COM2 端口初始化为 4800 波特 / 秒, 8 位数据位,无校验, 1 位终止位。 4 、在 A 、 B 两台微机之间实现串行通信, A 机发送, B 机接收。要求把 A 机中的 200 个字符传送到 B 机中。 分析: CPU 与 8251 之间采用查询方式控制数据传输过程,异步传送。发送方 CPU 每查询到 TXRDY 有效,则向 8251A 并行输出一个字节数据;接收方 CPU 每查询到 RXRDY 有效,则从 8251 接收一个字节数据,一直进行到全部数据传送完毕为止。假设传送时数据位为 2 位、 1 位停止位、波特率因子为 64 、偶校验。 8251 的命令 / 状态端口地址为 309H ,数据端口为 308H 。
个人分类: 生活点滴|12668 次阅读|3 个评论
汇编语言实验手册前言
求新 2009-2-16 12:25
实 验 手 册 《汇编语言程序设计》配套教学资料 程学先 林姗 程传庆 前 言 本手册为配合汇编语言程序设计课程的教学而设计,为机械工业出版社出版、我们所编写的《汇编语言程序设计》配套教学资料。本手册包括教材全部软件设计课程内容的实验。关于接口部分实验,需根据所选用实验器材决定,例如如果采用超想-30000TC综合实验/仿真系统组织实验,该系统配有实验讲义,可以按其实验讲义安排实验内容。 本手册由浅入深、由简单到复杂,共安排16组实验,108道题,大多数实验题都提供了实现程序,而且为电子版,可以直接复制、编译、运行,目的是节省代码录入与调试的时间,以往汇编实验一般要求完成20余道实验题,采用电子版实验教材使能在有限时间内更多地接触应用程序,更好地配合理论的学习,深入掌握汇编程序设计的基本理论、基本概念与基本方法。但是,过于简单的操作不利于对程序的理解、不利于培养创新精神、不利于记忆,也防碍培养程序调试的能力。因此,希望读者正确对待本手册,在进入实验后,即使是对于有实现程序的题,也要尽量争取独立完成,再与参考答案对照。有些题可以先简单阅看参考答案,再设法自己编程调试并完成。即使是直接复制,在运行之后,也要认真对照程序,分析程序的结构,了解程序运行过程,记忆其算法、程序设计方法与设计技巧。 为了取得最大成效,建议本手册不直接完整地发到学生手中,而只由教师掌握,根据教学进度与培养的需要,分次拷贝给学生。本手册前四个实验为认识性实验,可以直接复制拷贝原程序,上机编译执行,再分析程序结构与编译执行过程,对汇编语言程序建立感性认识。实验5到8为基本汇编程序设计,手册中提供了一些常用程序段,作为完成实验题的素材,使能快速完成有关实验题。这些程序段也要求学习者背记并熟练掌握。实验9之后为综合性较强练习题,包括极少量难度较大的题,排版时将题与参考程序分开,建议教师先提供实验题,在学生充分研讨后再提供参考程序,以期最有效地调动学生学习积极性与能动性,培养独立思考精神与创新精神。 本手册将提交机械工业出版社网站,向教师发布。为配合本学期教学,将在本博客上按周刊出当周实验内容,请读者跟着进度安排学习。 特别欢迎老师与同学对本手册提出宝贵意见,我们将选择新的实验内容及有关实验题的新的解法补充到将来更新的实验手册中,同时将提供者加入到新版实验手册的作者群中。 目 录 前 言1 实验1 认识性实验5 实验2 数据转换实验8 实验3 简单数据运算程序设计13 实验4 涉及压缩BCD码数据的转换程序及DEBUG练习16 实验5 算术运算程序设计25 实验6 自编有关双精度数据运算及逻辑运算、移位程序31 实验7 循环程序设计练习38 实验8 用循环程序设计方法解串操作问题实验45 实验9 利用子程序实现数据变换与数据处理的程序设计52 实验10 利用子程序进行串处理及有关日期的程序设计72 实验11 宏汇编程序设计84 实验12 递归程序与浮点运算92 实验13 BIOS功能调用程序设计106 实验14 有关声音的程序设计119 实验15 文件处理129 实验16 结构、条件汇编与驻留程序设计147 附录 输入输出程序设计164
个人分类: 生活点滴|6362 次阅读|1 个评论
重IDE而轻语言,谈谈Delphi的衰落
热度 1 陈小斌 2009-1-15 18:46
选择Delphi作为主要的程序设计工具和语言,实际上是非常偶然的。2000年来到北京读博士,那时我只会FORTRAN语言,但非常羡慕那些可视化的程序设计者,能够将自己的算法研究做成容易推广使用的软件,于是自己也打算学一门。最开始我选择的是JAVA,买了本Visual J++的书。书还没看一半,SUN和微软打起了官司,结果微软输了,Visual J++不再进一步维持和开发,我的心真是凉了半截。那个时候对于程序语言和开发工具还不是非常了解。听得最多的是VB和VC(主要是微软势力大,宣传多的原因),不选择VB的主要原因是VB是解释执行的,我总觉得会太慢(JAVA也是解释性语言,但那本Visual J++的书吹嘘其JIT编译器极其优秀,编译出来的程序运行速度超过C);不选择VC的原因,并不是因为其难,而是因为我特别不喜欢C语言的那一套符号表述,怪怪的,感觉像咒语。Delphi据说是搞数据库的,而我当时对数据库基本没有兴趣。 一个偶然的机会,我在学院路的高教书店里翻看程序设计方面的书。翻来翻去总觉得有一种语言看起来特别舒服,比我当时喜欢的FORTRAN90 的语法风格还顺眼,感觉流畅得像一篇英文。这些书都是有关Delphi程序设计的书。我一下子来了兴趣,得!不是挑了这么久了,就下决心学Delphi吧。此后,我就和Delphi结下了不解之缘,迄今未已。 Delphi Pascal确实是一种非常优雅的程序设计语言。学习过程中觉得其逻辑非常严谨。我经常能从中找到举一反三的快乐。比如分号;的应用,应该什么时候加,什么时候省略,从一种情况可以推出另一种来。还有Begin..End的加不加的场合,也是清清楚楚的逻辑。那个时候,这些简单的逻辑推演会给我带来好些快乐。但是,在很长一段时间里,我一直对Deilphi Pascal的面向对象语言特征和程序构架知之甚少。大概是过了一年,我才知道Delphi里面自己也可以撰写封装类。而有关继承、多态的理解与应用更是直到2006年的时候,2007年才开始理解有关接口的概念。 熟悉程序设计语言的朋友们一定会觉得非常诧异,我学习面向对象程序设计居然经历了如此漫长的过程。我想其中大部分不能怨我,而应该怨Delphi和大部分有关Delphi的宣传。Delphi实在太好上手了。鼠标拖拖拉拉,寥寥几句源码就可以开发出像模像样Windows可视化软件。当时有多少人为这种RAD程序设计方式而欢欣鼓舞!同时,Delphi为了保持对Pascal语言的兼容,是完全支持过程式开发的,偏偏我在过程式语言(FOTRTRAN)编程方面有较深的功底,习惯一时难以更改。更主要的是,从Borland到Delphi大部分专业级用户,对Delphi的宣传和介绍主要集中在IDE上,不断强化所谓的RAD开发功能,而有关语言本身介绍得很少。当时的市面上基本上没有专门讲解DelphiPascal语法的书籍。不像JAVA和后来的C#,许多专著专门讲语言,以语言为核心,而IDE则可以五花八门,属于另外一块内容。 这种对IDE的片面选宣传,使得许多人不知道Delphi实际上也是一种非常出色的面向对象的程序设计语言。在Delphi的发展历史上,曾多次引入创新性的程序设计理念。比如当前流行的单根类继承模式,就是从Delphi开始的;现代面向对象程序设计中的重要概念接口(Interface)也是在Delphi Pascal中率先引入的。利用接口的多根继承弥补了单根继承的不足,又可以避免C++等语言中多重类继承的缺点。利用Delphi语言本身开发的VCL曾经是世界上最先进的程序设计框架(Framwork),是Delphi的瑰宝,至今依然散发着迷人的魅力。可以说,在面向对象的程序设计发展史上,Delphi Pascal具有承前启后的重要作用。然而,在强大的IDE的宣传下,Delphi中这些本质性的东西被湮没了,Delphi的一般用户了解不多,而不用Delphi的人基本上不知道。我的一位在北航读电子商务(计算机专业)博士的同学,在他导师的要求下用Delphi 做了几个项目,但始终不知道在Delphi中也能自己定义类,这实在是很令人遗憾的。 确实,对IDE,尤其是对其RAD的强势宣传,使得Delphi当时吸引了一大批初学者。然而,随着软件开发工具不断的竞争升级,当RAD变得不再神奇的时候,Delphi的厄运开始来临了。Delphi对语言的垄断使得Delphi Pascal的编译器独此一家,缺乏应有的竞争机制,同时也导致Delphi Pascal社区本身市场的不足。重快手培训而不重内功磨练的市场模式终将遭到应有的惩罚。加上当时的Borland公司的方向性决策错误(如Delphi7以后曾一度准备放弃WIN32平台,全面转向.Net),因此,大约自Delphi7以后,尽管Delphi版本不断升级改变,但没有得到广泛应用,许多Delphi程序员转向JAVA或者C#,Delphi的影响逐渐衰落。 当然,我还是很喜欢Delphi的,也一直没有重新学习另外一种语言,尽管这肯定不是什么难事了。而且,Delphi本身也一直在不断发展和进步。从Delphi2006开始,我期盼已久的运算符重载功能终于得以支持,这意味着关于复数的运算,不再像原来那样全部依赖函数,那么晦涩难懂了。 Delphi目前不再是引领前进的步伐,而是在追赶时代的潮流。我非常希望一些Delphi应用大家们能够好好地写几本Delphi Pascal语言的专门论著,更希望能够有其他Pascal系列的新语言出现,就像JAVA和C#继承自C、C++一样。但这,也许仅仅是一个梦吧。
个人分类: 一孔之见|19621 次阅读|5 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-11 19:27

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部