按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 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 一个典型的窗口
窗口一般由屏幕上的矩形区域组成,不同的窗口可能包括一些相同的组成部分,如标题栏、菜单、工具栏、边框和状态栏