看到很多同学不会使用,虽然我也没有学到那一章,但是之前看过别的教程。现在贴出来供大家参考.
首先你得下载一个MASM,这个不是debug,不是系统自带的,然后杀毒,解压到某一盘的根目录下面。
下面是教程:
汇编实践○三九:代码的包装
如果以前我们给那些代码称之为“裸代码”的话,我们这一讲给大家讲一讲如何将我们的代码进行包装。
为什么要包装?原因有以下几个方面:
第一:包装的确的很好,给我们的感觉是程序,而不是代码。
第二:包装很精美,让人赏心悦目。
第三:包装可以得到以前你想到不敢想的东西。
第四:包装很奇妙,可以将好多的东西封装起来,好像一个黑箱。
第五:包装可以使得我们的代码优美,相互关系亲密
第……
……
可能你一定不想让我说了,说实话,如果没有这个包装,你的程序就只能是一些很简单的功能,显示个什么字符啊,或者做个加减法啊什么的,而你无论如何不能使代码间能够很好地配合工作,以达到自己想要达到的目的。
行了,不说那么多废话了,我们这就讲讲什么是包装。什么是汇编语言的包装。
我们以前所使用的指令,我们称之为机器指令,而我们在包装物上也有一些指令,我们称之为“伪指令”。也有一些书上会称之为:真指令,假指令,哎,我们别管那么多。
我们包装物上的东西肯定不是给人们用的,那有什么用呢?这些指令是给我们的汇编程序看的。
好,我们就来看看汇编的过程。不知大家有没有下载牛刀给大家提供的MASM,你下载后记得杀一下毒,然后放到一个根目录下,牛刀的就放在F:盘的根目录下:
F:\>CD MASM
F:\MASM>DIR/W
驱动器 F 中的卷是 测试磁盘
卷的序列号是 3499-0F55
F:\MASM 的目录
[.] [..] CREF.EXE DIV.COM LIB.EXE LINK.EXE MASM.EXE
5 个文件 216,144 字节
2 个目录 2,896,384 可用字节
F:\MASM>
那一个DIV.COM是上一讲我们做的一个文件,可以将之删了,怎么删大家还记得吧?算了,不删了,无所谓。
我们的MASM.EXE 就是汇编程序,我们的伪指令就是给她看的。
既然如此,我们先与这些伪指令见见面吧:(我们的原则也是,用到哪说到哪)。
请在MASM目录下执行:EDIT KNF001.ASM
注意按回车,EDIT是一个编辑器,而后面的KNF001.ASM是我们起的一个文件名,文件名什么都可以,但一定要以ASM为扩展名,否则我们的汇编编译器拒绝承认。(当然你也可以用其他扩展名试试看,这是牛刀想当然说的话,不能当真啊)。
反正我们习惯使用.ASM结尾的名子:
于是进入了汇编的程序,我们输入下面的代码:
ASSUME CS:CODE
CODE SEGMENT
MOV AH,4CH
INT 21H
CODE ENDS
END
大家注意哟,前面空多少格并不影响指令的执行,空格只是为了好看,如果我们写成如下形式:
ASSUME CS:CODE
CODE SEGMENT
MOV AH,4CH
INT 21H
CODE ENDS
END
你看这段代码是什么感觉呢?所以我们说:汇编语言我们也要讲求一点汇编的代码风格,汇编很难象高级语言那样要求风格很严格,但基本的缩进最好还是注意一点,自己读代码也服务是不?
ASSUME 假设
假设什么呢?假设CS的内容为CODE 注意,CODE是我们随便取的,一定要有这个假设,如果没有这个假设,我们做下面一个程序:
A SEGMENT
MOV AH,4CH
INT 21H
A ENDS
B SEGMENT
MOV AH,4CH
INT 21H
B SEGMENT
END
这也是一段程序,可这里面有两个部分,就是两个段,我们用SEGMENT表示段开始的标志,而ENDS为段结束的标志,这两个程序都是正确的啊,可程序到底从哪儿开始执行呢?
你可能说了:顺序执行呗,不见得吧,如果一开始我们用了一个ASSUME CS:B,一切就都变了。
好了,我们再来继续理解我们的包装材料:
ASSUME CS:CODE
CODE SEGMENT
MOV AH,4CH
INT 21H
CODE ENDS
END
CODE:这就是一个名子,和上面的A,B一样,仅仅是一个名子而已,不要看到CODE就是代码段了,还要看ASSUME CS: 后面指的是不是这个段。
既然是个名子,我们就提提这个名字的起法。其实挺复杂,我们就知道我们用几个字母就没错,当然不能是我们指令中所使用的指令啊,当然也不能与伪指令重复,否则编译器认不识是我们的名子,还是指令了是不?
当然也有一些规则,什么第一个不能为数字啊,什么字母只能打头啊,大家知道,那是让人家考试做判断选择题用的。你如果真的将名子起错了,编译器也不会让你的,呵呵,事实就是如此。
当然我们起名子最好有点意义,那样我们才能够在使用中不至于以后看到这个名子不知道什么意思是不是?
行了,我们上面就是最基本的程序了,当然为了使得我们的程序能够在执行后有上个显示,我们在屏幕上打一个小笑脸符吧,大家还记得吧?笑脸符的值为1入口参数为DL,调用参数为AH=02H,21号指令:
File Edit Search View Options Help
┌─────── F:\MASM\KNF001.ASM ──────────────────────┐
│ASSUME CS:CODE ↑
│ █
│CODE SEGMENT █
│ MOV AH,02H █
│ MOV DL,1H █
│ INT 21H █
│ █
│ MOV AH,4CH █
│ INT 21H █
│CODE ENDS █
│ END █
│ █
│ █
│ █
│ █
│ █
│ █
│ █
│ █
│ █
│ █
│ ↓
F1=Help │ Line:4 Col:18
大家觉得这个窗口怎么样?呵呵,按FILE/SAVE 保存一下,然后再按FILE/QUIT 退出。(鼠标可以按的,当然你如果是高用也可用ALT+F来选,或者按F10来选。)
行了,回到DOS系统,我们用DIR,会看到多了一个文件KNF001.ASM
接下来我们就要进行汇编了,按MASM KNF001.ASM
F:\MASM>MASM KNF001.ASM
Microsoft (R) Macro Assembler Version 5.00
Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved.
Object filename [KNF001.OBJ]:
Source listing [NUL.LST]:
Cross-reference [NUL.CRF]:
50158 + 449634 Bytes symbol space free
0 Warning Errors
0 Severe Errors
F:\MASM>
一路回车,其实是问我们要不要几个文件,我们不要好了,我们目前才学习阶段,也不会需要一些文件存档啊,或者阅读代码的,当然没必须有些这文件啦,当然如果你好奇,也可以将一些文件命名下来看看,看里面是什么。
当然如果真的一路回车,还有一个简单的方法,就是在命令打完后,后面加一个分号,就一下子将结果给出来了,挺方便。
还有一点就是,如果我们编译没通过,编译器也会将我们目前处于哪一行代码有错误,显示出来,我们要回来EDIT 编辑器中继续改正,一直到产生了OBJ文件:
即,我们看结果应该产生了一个KNF001.OBJ文件喽。
有了这个文件,我们就可以用链接器进行连接了。
LINK KNF001
注:不需要扩展名。
也是一路回车,于是就回出现KNF001.EXE
当然要方便,也可以在后面加一个分号,牛刀就用这个办法:
F:\MASM>LINK KNF001;
Microsoft (R) Overlay Linker Version 3.60
Copyright (C) Microsoft Corp 1983-1987. All rights reserved.
LINK : warning L4021: no stack segment
F:\MASM>
这种方法快啊。
我们再来运行这一程序看看,当然我们可以用DIR看看产生这个文件没有。
F:\MASM>DIR/W
Volume in drive F is ????
Volume Serial Number is 3499-0F55
Directory of F:\MASM
[.] [..] CREF.EXE DIV.COM KNF001.ASM KNF001.EXE
KNF001.OBJ LIB.EXE LINK.EXE MASM.EXE
8 File(s) 216,881 bytes
2 Dir(s) 2,880,000 bytes free
F:\MASM>KNF001
?
F:\MASM>
与想像的一样,产生了KNF001.EXE文件,运行效果也很好(没办法,复制下来的效果不好)。
我们如何将这一程序调进DEBUG中呢?
只需要在DEBUG后面加入文件名就行了(注意,“.EXE”一定不能少啊)。
F:\MASM>DEBUG KNF001.EXE
-U
0BE0:0000 B402 MOV AH,02
0BE0:0002 B201 MOV DL,01
0BE0:0004 CD21 INT 21
0BE0:0006 B44C MOV AH,4C
0BE0:0008 CD21 INT 21
我们汇编一看,果然是我们编写的程序。当然你也可以单步执行啊,一样的。或者作程序的调试啊。这样一来,我们就将我们的汇编环境与DEBUG环境完美地统一起来了。。
对了,我们在伪指令中,还有一个END命令表示汇编结束啊,没什么特别的意思(噢,有特别的意思,我们以后再说)。
想要做一个程序,我们必须知道一些中断功能,我们接下来一每一讲都给大家提供一些中断的入口参数,出口参数与功能提示,这次我们提供的为字符中断,中断号INT 21H:
(1)、功能01H、07H和08H
功能描述: 从标准输入设备(如:键盘)读入一个字符。
该中断在处理过程中将一直处于等待状态直到有字符可读为止。
该输入还可被重定向,如果这样做,则无法判断文件是否已到文件尾
入口参数:
AH=01H,过滤掉控制字符,并回显
=07H,不过滤掉控制字符,不回显
=08H,过滤掉控制字符,不回显
出口参数: AL=输入字符的ASCII码
(2)、功能02H
功能描述: 向标准输出设备(如:屏幕)输出一个字符。
该输出还可被重定向,如果这样做,则将无法判断磁盘是否满
入口参数:
AH=02H
DL=待输出字符的ASCII码
出口参数: 无
(3)、功能03H
功能描述: 从辅助设备读入一个字符,该辅助设备的缺省值为COM1
入口参数: AH=03H
出口参数: AL=读入字符的ASCII码
(4)、功能04H
功能描述: 向辅助设备输出一个字符,该辅助设备的缺省值为COM1
入口参数: AH=04H
DL=待输出字符的ASCII码
出口参数: 无
(5)、功能05H
功能描述: 向标准的输出设备输出一个字符。该缺省的输出设备为LPT1端口的打印机,除非用MODE命令来改变
入口参数:
AH=05H
DL=待输出字符的ASCII码
出口参数: 无
(6)、功能06H
功能描述: 控制台(如:键盘、屏幕)输入/输出。如果输入/输出操作被重定向,那么,将无法判断文件是否已到文件尾,或磁盘已满
入口参数: AH=06H,DL=输入/输出功能选择
出口参数: 若DL=00H-FEH,则此功能为输出,DL为待输出字符的ASCII码;
若DL=0FFH,则此功能为输入,此时:若ZF=1,则无字符可读,否则,AL=读入字符的ASCII码
(7)、功能09H
功能描述: 输出一个字符串到标准输出设备上。如果输出操作被重定向,那么,将无法判断磁盘已满
入口参数: AH=09H
DS:DX=待输出字符的地址
说明:待显示的字符串以’$’作为其结束标志
出口参数: 无
(8)、功能0AH
功能描述: 从标准输入设备上读入一个字节字符串,遇到“回车键”结束输入(输入的字符在标准的输出设备上有回显)。如果该输入操作被重定向,那么,将无法判断文件是否已到文件尾
入口参数: AH=0AH
DS:DX=存放输入字符的起始地址
接受输入字符串缓冲区的定义说明:
1、第一个字节为缓冲区的最大容量,可认为是入口参数;
2、第二个字节为实际输入的字符数(不包括回车键),可看作出口参数;
3、从第三个字节开始存放实际输入的字符串;
4、字符串以回车键结束,回车符是接受的最后一个字符;
5、若输入的字符数超过缓冲区的最大容量,则多出的部分被丢弃,系统并发出响铃,直到输入“回车”键才结束输入。
例如:
BUFF 80, ?, 80 DUP(?) ;最多接受80个字符
出口参数: 无
(9)、功能0BH
功能描述: 检查标准输入设备上是否有字符可读。该输入操作可被重定向
入口参数: AH=0BH
出口参数: AL=00H——无字符可读;FFH——有字符可读
(10)、功能0CH
功能描述: 清空当前的标准输入缓冲区,再读入字符。其输入操作可被重定向
入口参数: AH=0CH
AL=01H、06H、07H、08H或0AH
出口参数: 若入口参数AL为0AH,则DS:DX=存放输入字符的起始地址,否则,出口参数AL=输入字符的ASCII码
教程结束。
如果有朋友喜欢这个教程的话,我可以给你。
很简单易懂,适合连二进制的基础都没有的朋友。