windows环境下32位汇编语言程序设计-第8章
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
程序的排版风格应该遵循以下规则。
首先是大小写的问题,汇编程序中对于指令和寄存器的书写是不分大小写的,但小写代码比大写代码便于阅读,所以程序中的指令和寄存器等要采用小写字母,而用equ伪操作符定义的常量则使用大写,变量和标号使用匈牙利表示法,大小写混合。
其次是使用Tab的问题。汇编源程序中Tab的宽度一般设置为8个字符。在语法上,指令和操作数之间至少有一个空格就可以了,但指令的助记符长度是不等长的,用Tab隔开指令和操作数可以使格式对齐,便于阅读。如:
xor eax;eax
fistp dwNumber
xchg eax;ebx
上述代码的写法就不如下面的写法整齐:
xor eax;eax
fistp dwNumber
xchg eax; ebx
还有就是缩进格式的问题。程序中的各部分采用不同的缩进,一般变量和标号的定义不缩进,指令用两个Tab缩进,遇到分支或循环伪指令再缩进一格,如:
。data
dwFlag dd ?
de
start:
mov eax;dwFlag
。if dwFlag 1
call _Function1
。else
call _Function2
。endif
…
合适的缩进格式可以明显地表现出程序的流程结构,也很容易发现嵌套错误,当缩进过多的时候,可以意识到嵌套过深,该改进程序结构了。
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第3章 使用MASM
3。6 代 码 风 格(2)
2。 注释和空行
没有注释的程序是很难维护的,但注释的方法也很有讲究,写注释要遵循以下的规则:
● 不要写无意义的注释,如“将1放到eax中”,“跳转到exit标号处”等。
● 修改代码同时修改相应的注释,以保证注释与代码的一致性。
● 注释以描写一组指令实现的功能为主,不要解释单个指令的用法,那是应该由指令手册来完成的,不要假设看程序的人连指令都不熟悉。
● 对于子程序,要在头部加注释说明参数和返回值,子程序可以实现的功能,以及调用时应该注意的事项。
由于汇编语言是以一条指令为一行的,实现一个小功能就需要好几行,没有分段的程序很难看出功能模块来,所以要合理利用空行来隔开不同的功能块,一般以在高级语言中可以用一句语句来完成的一段汇编指令为单位插入一个空行。
3。 避免使用宏
在MASM的宏功能中最好只使用条件汇编,用来选择编译不同的代码块来构建不同的版本,其他如宏定义和宏调用只会破坏程序的可读性,能够不用就尽量不用,虽然展开后只有一两句的宏定义不在此列,但既然展开后也只有一两句,那么和直接使用指令也就没有什么区别了。
在汇编中避免使用宏定义的理由是:汇编中随时要用到各个寄存器,宏定义不同于子程序,可以有选择地保护现场,在使用中很容易忽略里面用了哪个寄存器,从而对程序结构构成威胁。高级语言的宏定义则不会有这个问题。
笔者曾经见到过最极端的使用宏定义的程序是MicroMedia的Director SDK,100行左右的例子中几乎有90%都是宏定义,虽然例子很容易改成其他功能的程序,但要在里面加入新的功能则几乎是不可能的,因为程序中连C语言函数开始和结束的花括号都被改成了宏定义,这样一来,如果要真正使用这个开发包,则必须把宏定义“翻译”回原来的样子才能真正理解程序的流程。对于这样的代码,笔者是绝对不敢苟同的。
3。6。3 代码的组织
程序中要注意变量的组织和模块的组织方式。
过多的全局变量会影响程序的模块化结构,所以不要设置没必要的全局变量,尽量把变量定义成局部变量。把仅在子程序中使用的变量设置为局部变量可以使子程序更容易封装成一个黑匣子,如果无法把全部变量设置为局部变量,则尽量把这些数据改为参数输入输出,如果无法改为参数,那么意味着这个子程序不能不经修改地直接放到别的程序中使用。
在主程序中使用比较频繁的部分,以及便于封装成黑匣子在别的程序上用的代码,都应该写成子程序,但一个子程序的规模不应该太大,行数尽量限制在几百行之内,功能则限于完成单个功能。对于子程序,定义参数的时候要尽可能精简,对可能引起程序崩溃的参数,如指针等,要进行合法性检测。
子程序中在使用完申请的资源的时候,注意在退出前要释放所用资源,包括申请的内存和其他句柄等,对于打开的文件则要关闭。
对于程序员来说,开发每一个软件都要从头做起是很浪费时间的,一般的做法是从自己以前做过的程序中拷贝相似的代码,但修改还是要花一定的时间,最好的办法就是尽量把子程序做成一个黑匣子,可以不经修改地直接拿过来用,这样,每次编程相当于只是编写新增的部分,随着代码的积累,开发任何程序都将是很快的事情。
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第4章 第一个窗口程序
4。1 开始了解窗口(1)
4。1。1 窗口是什么
窗口是什么?大家每天在使用Windows,屏幕上的一个个方块就是一个个窗口!那么,窗口为什么是这个样子呢?窗口就是程序吗?
1。 使用窗口的原因
回想一下DOS时代的计算机屏幕,在1990年Windows 3。0推出之前,计算机的屏幕一直使用文本模式,黑洞洞的底色上漂浮着白色的小字,性能不高的图形模式只用于游戏和一些图形软件。对DOS程序来说,屏幕是惟一的,上面有个光标表示输入字符的位置,程序运行后往屏幕输出一些信息,退出时输出的信息就留在了屏幕上,然后是第二个程序重复这个过程,当屏幕被写满的时候,整个屏幕上卷一行,最上面一行被去掉,然后程序在最底下新空出来的一行上继续输出。
对于一个单任务的操作系统,这种方式是很合理的,因为平时使用传真机或打字机就是用上卷的方式来容纳新的内容的。但是如果是多任务呢?两个程序同时往屏幕上写东西或者两个人同时往打字机上打字,那么谁都看不懂混在一起的是什么。DOS下的TSR(内存驻留)程序是多个程序同时使用一个屏幕的例子,但实质上这并不是多任务,而是TSR将别的程序暂时挂起,挂起的程序不可能在TSR执行期间再向屏幕输出内容,TSR在输出自己的内容之前必须保存屏幕上显示的内容,并在退出的时候把屏幕恢复原来的样子,否则挂起的程序并不知道屏幕已经被改变,在这个过程中,DOS不会去干预中间发生的一切。
Windows是多任务的操作系统,可以同时运行多个程序,同样,各个程序在屏幕上的显示不能互相干扰,而且,多个程序可以看成是“同时”运行的,在后台的程序也可能随时向屏幕输出内容,这中间的调度是由Windows完成的。Windows采用的方法是给程序一块矩形的屏幕空间,这就是窗口。应用程序通过Windows向属于自己的窗口显示信息,Windows判断该窗口是不是被别的窗口挡住,并把没有挡住的部分输出到屏幕上,这样屏幕上显示的东西就不会互相覆盖而乱套。对于应用程序来说,它只需认为窗口就是自己拥有的显示空间就可以了。
2。 窗口和程序的关系
既然不同窗口的内容就是不同程序的输出,那么一个窗口就是一个程序吗?反过来,一个程序就是一个窗口吗?
答案是否定的,一个窗口不一定就是一个程序,它可能只是一个程序的一部分。一个程序可以建立多个顶层窗口,如Windows的桌面和任务栏都是顶层窗口,但它们都属于“文件管理器”进程,所以并不是一个窗口就是一个程序的代表。Windows的窗口采用层次结构,一个窗口中可以建立多个子窗口,如窗口中的状态栏、工具栏,对话框中的按钮、文本输入框与复选框等都是子窗口。子窗口中还可以再建立下一级子窗口,如Word工具栏上的字体选择框。
反过来,运行的程序并非一定就是窗口,比如悄悄在后台运行的木马程序就不会显示一个窗口向用户报告它在干什么。在Windows NT下用“任务管理器”查看,进程的数量比屏幕上的窗口多得多,意味着很多的运行程序并没有显示窗口。如果一个程序不想和用户交互,它可以选择不建立窗口。
所以本章的标题“第一个窗口程序”指学习编写第一个以标准的窗口为界面的程序,而不是泛指Windows程序。如果要写的Win32程序不是以窗口为界面的,如控制台程序等,就不一定采用本章中提及的以消息驱动的程序结构。
虽然以窗口为界面的程序并不是所有Windows程序的必然选择,但绝大部分的应用程序是以这种方式出现的,从操作系统的名称“Windows”就可以看出这一点,了解窗口程序就是相当于在了解Windows工作方式的基础。
4。1。2 窗口界面
大部分的窗口看上去都是大同小异的,先来看一个典型的窗口,即Windows附带的写字板,如图4。1所示。用它来说明窗口的各个部分。
图4。1 一个典型的窗口
窗口一般由屏幕上的矩形区域组成,不同的窗口可能包括一些相同的组成部分,如标题栏、菜单、工具栏、边框和状态栏等,每个部分都有自己固定的行为模式:
● 窗口边框——窗口的外沿就是窗口边框,用鼠标按住边框并拖动可以调整窗口的大小。
● 标题栏——窗口的最上面是标题栏,用鼠标按住标题栏拖动可移动窗口,双击标题栏则将窗口最大化或从最大化的状态恢复。通过标题栏的颜色可以区分窗口是不是活动窗口,同时标题栏列出了应用程序的名称。
● 菜单——标题栏下面是菜单,单击菜单会弹出各种功能选择。
● 工具栏——菜单的下面是工具栏,工具栏上用图标的方式列出最常用的功能,相当于菜单的快捷方式。
● 图标和“最小化”、“最大化”与“关闭”按钮——图标位于标题栏的左边,三个控制按钮则位于标题栏的右边。单击图标会弹出一个系统菜单,双击图标则相当于按下了“关闭”按钮。“最小化”、“最大化”按钮用来控制窗口的大小。
● 状态栏——状态栏位于窗口的最下面,用来显示一些状态信息。
● 客户区——窗口中间用来工作或输出的区域,叫做窗口的客户区,把窗口看做是一张白纸的话,客户区就是白纸中真正用来写东西的部分,程序在这里和用户进行交互。
● 滚动条——如果客户区太小不足于显示全部内容,右边或底部可能还有滚动条,拖动它可以滚动窗口的客户区,以便看到其他的内容。
虽然大部分窗口看上去都差不多,但并不是每个窗口都有这些东西,也许有的窗口就没有图标和最小化、最大化框,有的没有工具栏或状态栏,有的没有标题栏,而有的就干脆是个奇怪的形状,如Office帮助中的助手,那些小狗小猫都是些不折不扣的窗口,Windows的桌面和桌面下面的任务栏也都是窗口,就连屏幕保护的黑屏幕也是一个大小为整个屏幕、没有标题栏和边框的窗口!
一致的窗口形状和行为模式为Windows用户提供了一致的用户界面,几乎所有的窗口程序都在菜单的第一栏设置有关文件的操作和退出功能、最后一栏设置程序的帮助,相同的功能在工具栏上的图标也是大同小异的,用户可以不再像在DOS下那样,对不同的程序需要学习不同的界面,用户自从学会使用第一个软件起,就基本学会了所有Windows软件的使用模式,而且可以通过相似的菜单、工具栏等来发掘程序的新功能。窗口的菜单和客户区则是最个性化的东西,菜单随程序功能的不同而不同,而客户区则是窗口程序的输出区域,不同的程序在客户区内显示了不同的内容。
4。1。3 窗口程序是怎么工作的
1。 窗口程序的运行模式
对程序员来说,要了解的不仅是用户可以看到的部分,还必须了解窗口底下的东西,了解用怎样的程序结构来实现窗口的行为模式。
DOS程序员熟悉的是顺序化的、按过程驱动的程序设计方法。程序有明显的开始、明显的过程和明显的结束,由程序运行的阶段来决定用户该做什么。而窗口程序是事件驱动的(再次提醒:这里是“窗口程序”而不是“Windows程序”,因为和窗口有关的程序才是事件驱动的,其他的Windows可能并不这样工作,如控制台程序的结构还是同DOS程序一样是顺序化的,但与窗口相关的Windows程序占了绝大多数,所以大部分的书籍中讲到Windows程序就认为是事件驱动的程序),用户可能随时发出各种消息,如操作的过程中觉得窗口不够大了,就马上会拖动边框,程序必须马上调整客户区的内容以适应新的窗口大小;用户觉得想先干别的事情,可能会把窗口最小化,关闭按钮也有可能随时被按下,这意味着程序要随时可以处理退出的请求。如果非要规定干活的时候不能移动窗口与调整大小,那么这些窗口就会呆在桌面上一动不动。
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第4章 第一个窗口程序
4。1 开始了解窗口(2)
先通过一个简单的例子来说明两种程序设计方式的不同,以DOS下的文件比较命令p为例,程序运行时先提示输入第一个文件名,然后是输入第二个文件名,程序比较后退出,同时把结果输出在屏幕上。假如有一个窗口版的p程序,那么运行时会在屏幕上出现一个对话框,上面有两个文本框用来输入两个文件名,还会有个“比较”按钮,按下后开始比较文件,用户可以随时按下“关闭”按钮来退出程序。
两种程序的运行会有相当大的不同,如图4。2所示,DOS程序必须按照顺序运行,当运行到输入第二个文件名时,用户不可能回到第一步修改第一个文件名,这时候用户也不能退出(除非用户强制用Ctrl+C键,但这不是程序的本意);而在窗口程序中用户可以随意选择先输入哪个文件名,同时也可以对窗口进行各种操作,当用户做任何一个操作的时候,相当于发出了一个消息,这些消息没有任何顺序关系,程序中必须随时准备处理不同的消息。
图4。2 不同的程序结构模式
这就决定了窗口程序必定在结构上和DOS程序有很大的不同,窗口程序实现大部分功能的代码应该呆在同一个模块——图中的“消息处理”模块中,这个模块可以随时应付所有类型的消息,只有这样才能随时响应用户的各种操作。
下面先来看一个地地道道的Win32汇编窗口程序。
2。 FirstWindow源代码
读者可以在所带光盘�