最近在学《微机原理》这门课,老师在课上讲了一大堆的汇编指令,听着脑袋都是晕的。如果能够实际的运行一下这些代码,或许对于理解这些指令有些帮助。有些同学可能也知道,使用C语言编程,需要一个编译器,不同平台的C语言都有不同的编译器,那么练习汇编的程序是不是也要去下载一个汇编器呢?确实,Windows
平台下也有好几种汇编器:Borland
公司的TASM
,Microsoft
公司的MASM
,还有开源的NASM
,不过,这些汇编器都有自带的一些伪指令和汇编程序的格式,如果一开始就使用他们,可能无法专注于汇编指令的学习,还要去学习怎么使用不同的汇编器。
其实,Windows
平台下自带了一个简单的汇编器——debug
。本来,debug
是程序员用来除错的,不过,它也可以汇编一些简单的汇编指令。使用它可以完全不用考虑宏汇编的一些伪指令,专注于汇编指令的执行。
##debug的用法
debug
是一个命令行程序,所以我们必须在命令提示符下使用,首先打开命令提示符(我一般使用运行命令输入cmd就可以了,你也可以进入开始菜单-附件-命令提示符 来运行它。)
(我以Windows XP
为例,Win7
下面也是类似的)
输入 debug
回车
这时,你可以看到一个以-开头的提示符,光标在这里闪,你可以输入一些 debug
的命令了。
##常用的debug命令
?
debug
的帮助,提供了一些可用命令的列表。a addr
CS:0100
这个地址,COM
文件规定,必须从0100开始。r reg
CS:IP
地址处的汇编代码。q
debug
。u startaddr endaddr
g addr
CS:IP
开始执行。上面讲的是一些用的比较多的debug
命令,更多的可以查找debug
的帮助。
##开始用 debug 写汇编程序。
进入debug
的提示符后,我们可以直接输入a命令,开始写我们的代码。
从图中 可以看到 前面的数字就是你当前指令的地址CS:IP
。
我们输入下面这段程序看看:
mov ah, 02
mov dl, 1
int 21h
int 20h
运行结果如上图,打印出了一个笑脸。上面的代码是什么意思呢?下面 我一行一行的解释。
mov ah, 02
将02 送到 ah,这里是为了调用后面的int 21
的中断程序,02是DOS系统里面的打印函数的功能号,你只要知道这句是调用打印函数就可以了。mov dl, 1
将1 送到 dl寄存器,这个寄存器所存的数值将被打印出来。你将字符的ASCII码值送入dl,调用int 21h
之后,这个字符就能打印出来了。
有一点要注意,debug里面的数字都是16进制的,但是在这里不要加h的后缀。int 21h
调用DOS系统的21号中断,这里的h后缀可加可不加。int 20h
返回DOS系统。这句在debug
的环境里可加可不加。下面,再来写一个打印出所有ASCII
码的小程序,代码如下图:
大家可以自己运行看看结果。
我们还可以把它保存成一个.com的可执行文件。
首先使用debug
的name
命令,将文件命名为ascii.com
:(下面命令前面的短横代表debug
里面的提示符,不必输入)
- n ascii.com
然后修改cx寄存器的值,这个寄存器里的值要修改为上面那个程序的大小,怎么看那个程序的大小呢? 看前面的地址,是从CS:0100
到CS:010F
可知,程序的大小为FH 个字节,于是输入以下代码:
- r cx
: 0007
修改之后,使用w命令保存文件:
- w
执行后会显示Writing 0000F bytes
。在debug
运行的目录下就会出现一个ascii.com
文件,以后只要把它复制到其他地方执行,就能打印出所有ASCII
码值了。
下面用一个指令的示例来讲讲如果使用debug
练习这个指令。
交换指令 XCHG dest, src
交换指令可以实现字节的交换,也可以实现字的交换。代码实例如下:
- a
0ADC:0100 mov ax, 52
0ADC:0103 mov bx, 41
0ADC:0106 xchg ax, bx
0ADC:0108
接下 我们可以使用debug
的r读取 ax和 bx的值
- r ax
AX 0000
:
- r bx
BX 0000
:
接着使用g 单步运行:
- g 100
- g 103
- g 106
- g 108
单步运行过程中会打印出所有寄存器的值,你可以发现寄存器值的变化。
##写在最后
看了上面的之后,我相信你应该能使用debug
练习各个8086汇编指令的运行,观察各种指令运行后的结果了。注意的是,debug
里面只能直接执行8086的指令,无法使用宏汇编、伪代码。而且也只支持写一些简单的.com文件,学到后面还是要使用各种宏汇编器(比如MASM
、NASM
.etc)。使用宏汇编器则需要了解那个汇编器特有的语法,如果定义段,如何定义宏,什么的。这些不同的汇编器都有不同的规定,而8086指令都是一样的(如果你是用Intel
的语法,实际上在Linux
系统中,8086经常使用一种AT&T
的语法,与Intel
的稍有不同)。
本站采用 知识共享署名-非商业性使用-相同方式共享3.0 中国大陆许可协议 进行许可,转载请注明出处。
推荐使用 chrome 浏览器浏览本站。