汇编语言(王爽第三版)实验1查看CPU和内存,用机器指令和汇编指令编程

标签:
汇编王爽it教育 |
分类: 汇编语言(王爽第三版)实验 |
实验前专题:开发环境搭建
目前我们能够搭建的开发环境:
【1】纯DOS环境(DOS6.22或以前版本);使用Edit编辑器对汇编代码编辑;可以使用微软的masm汇编编译器编译和连接。以后实验中也多次使用纯DOS环境。这个模式可以使用实模式方式。随着操作系统发展,这种方式基本绝迹了。
【2】XP系统下的虚拟模式(笔者使用的环境,特意装的XP系统,太低的系统都不好找了);使用notepad++ for windows对汇编代码进行编辑(对C语言也使用这个写代码);可以使用微软的masm汇编编译器编译和连接。debug程序在XP系统中自带的。
【3】通过Visual
【4】其他的一些集成实验环境,这里不介绍了。也不利于初学。
【5】高于XP系统版本的操作系统,我们需要DOS-BOX这个模拟程序来支持,如果在win7系统搭建汇编开发环境,请查阅相关介绍,这个窗口虽然可调,但是用着不爽。
实验1 查看CPU和内存,用机器指令和汇编指令编程
1.预备知识:Debug的使用
我们以后所有的实验中,都将用到debug程序,首先学习一下它的主要用法。
(1)什么是Debug?
Debug是DOS、Windows都提供的实模式(8086方式)程序的调试工具。使用它,可以查看CPU各种寄存器中的内容、内存的情况和在机器码级跟踪程序的运行。
(2)我们用到的Debug功能
R命令查看、改变CPU寄存器的内容;
D命令查看内存中的内容;
E命令改写内存中的内容;
U命令将内存中的机器指令翻译成汇编指令;
T命令执行一条机器指令;
A命令以汇编指令的格式在内存中写入一条机器指令。
P命令 到了 int 21H,我们要用P命令执行;进入循环时用p命令也可以退出循环
G命令g命令调试时能跳到想去的地址,特别是调试循环代码时
(3)进入Debug。(笔者使用的是XP系统)
直接在cmd窗口运行即可。
http://s13/mw690/006LW9dSzy7aXRNl46w2c&690
或在运行窗口键入cmd回车(书中win2000方式类似)
http://s8/mw690/006LW9dSzy7aXRORfcrd7&690
打开cmd窗口后,键入debug,如上图。
(4)用R命令查看、改变CPU寄存器的内容。由于开发环境的不同,cmd调试结果也是不同的,这里只是将它们的意义说明。
-r
AX=0000
DS=0B04
0B04:0100
E80400
看图说明:
【1】红色标记的是我们讲过的6中寄存器,其中ax,bx,cx,dx都是通用寄存器,但是它们也有特定的用途,以后慢慢了解。cs和ip寄存器是专门寄存器。
【2】0B04:0100
E80400
含义:CS=0B04
理解:这个CPU指向的地址cs:ip就是CPU将要读取并执行的指令代码。当然,这个代码对于我们来说是没有任何意义的。
在debug状态下,我们可以使用R命令修改上述寄存器的值。
例如:
r
cs
r
ip
r
ax
(5)使用D命令查看内存中的内容。
直接显示从某单元地址开始内容;
指令格式:d 段地址:偏移地址
例如:
-d 0b04:0
0B04:0000
0B04:0010
0B04:0020
0B04:0030
0B04:0040
0B04:0050
0B04:0060
0B04:0070
【1】中间的红色部分是从指定地址开始的内存单元中的内容,每一行为16个字节,用16进制格式输出。内存单元是从低地址向高地址显示的。在红色区域左边的是每行的起始地址(段地址:偏移地址);偏移地址的变化都是16的整数倍,在debug中就是10H。红色区域的右侧是将内存单元存储的值所对应的ASCII码字符,如果不在ASCII码的范围,以“.”形式列出(表示不可识别的ASCII码)。
【2】在debug中,使用D命令显示的内存单元,是为了便于我们调试程序时查看内存的状态。此处注意,真正的内存依然是单列、连续的线性存储空间。而不是像debug中显示的按照表的形式存在。
【3】使用d命令后,我们可以继续使用单个的“d”命令,继续显示连续的内存单元内容。每次显示128个单元(128个字节)内容。
【4】使用 d 段地址:偏移地址(开始) 偏移地址(结束)来显示一段连续内存单元的内容;例如:-d 0b04:0 7 显示的是从0~7共8个内存单元的内容。
(6)用Debug的E命令改写内存中的内容:
【1】可以使用E命令来改写内存中的内容,按照字节单元的方式修改
例如:-e
0b04:0
【2】可以使用E命令修改内存中内容,直接按照ASCII码的方式修改
例如:
-e 0b04:100
'a','b','c','d','e',1,'a+b'
-d 0b04:100
0B04:0100
【3】使用E命令修改代码段中指令的代码,这个太累了。不推荐。
(7)使用U命令查看指定内存单元开始的汇编代码和机器码。
-u 0b04:100
0B04:0100
E80400
0B04:0103
32C0
0B04:0105
AA
0B04:0106
C3
0B04:0107
B400
……
这里我们看见右侧的是汇编代码,中间的是机器码,左侧的是内存单元地址(物理地址)。
(8)使用t命令执行cs:ip指向的内存单元的指令,单步的执行。注意执行后,每个寄存器值的变化。
(9)使用A命令,以汇编指令的形式在内存中写入机器指令。
2. 实验任务
(1)使用debug,将下面的程序段写入内存,逐条执行,观察每条指令执行后CPU中相关寄存器中内容的变化。
打开cmd窗口(命令提示符窗口),键入debug;回车
-r
AX=0000
DS=0B04
0B04:0100
E80400
我们发现CS=0B04 ; IP=0100,也就是说CPU从这里读取代码并执行。我们也在这开始吧。(注:这个是我的系统debug,你的机器系统不一样,导致debug后寄存器状态不同。)
【1】首先使用E命令
-e
cs:100
0B04:0100
0B04:0108
-u cs:100
0B04:0100
B8204E
0B04:0103
051614
0B04:0106
BB0020
……太累了,此处省略一万字。将所有的机器码都使用上述方式用E命令写入到cs:100开始的内存单元中。
【2】使用a命令,直接写入汇编指令。
-a cs:100
0B04:0100 mov ax, 4e20
0B04:0103 add ax,1416H
0B04:0103 add ax,1416
0B04:0106 mov bx,2000
0B04:0109 add ax,bx
0B04:010B mov bx,ax
0B04:010D add ax,bx
0B04:010F mov ax,001a
0B04:0112 mov bx,0026
0B04:0115 add al,bl
0B04:0117 add ah,bl
0B04:0119 add bh,al
0B04:011B mov ah,0
0B04:011D add al,bl
0B04:011F add al,9c
我们使用d命令查看下这段内存的内容:
-d cs:100
0B04:0100
0B04:0110
0B04:0120
【3】怎么执行?使用T命令,确保cs存储的就是我们期望的代码段的段地址,ip存储的也是我们期望的开始偏移地址,如果不是,我们可以使用r命令修改cs或ip的值。
-r
AX=0000
DS=0B04
0B04:0100
B8204E
-t
AX=4E20
DS=0B04
0B04:0103
051614
执行完毕后,我们发现ax寄存器的值变化了。
按要求,逐步执行t命令,体会汇编指令导致寄存器变量值的变化。
(2)将下面3条指令写入从2000:0开始的内存单元中,利用这3条指令计算2的8次方。
【1】使用a命令在2000:0处写入这3条代码
-a 2000:0
2000:0000 mov ax, 1
2000:0003 add ax,ax
2000:0005 jmp 2000:0003
使用u命令我们查看下是否写入成功;
-u 2000:0
2000:0000
B80100
2000:0003
01C0
2000:0005
EBFC
【2】使用r命令查看寄存器状态
-r
AX=0000
DS=0B04
发现CS=0B04
使用r命令直接修改。
-r cs
CS 0B04
:2000
-r ip
IP 0100
:0
【3】使用t命令执行代码,注意观察ax值的变化。由于jmp 2000:0003指令导致这段程序流程为死循环,执行8次循环后,使用q命令直接退出吧。
(3)查看内存中的内容。
PC机主板上的ROM中写有一个生产日期,在内存FFF00H~FFFFFH的某几个单元中,请找到这个生产日期,并试图改变它。
【1】使用d命令查看内存单元的内容,由于物理地址是:FFF00H,我们可以假定偏移地址是0,那么段地址是FFF0H,也就是我们使用D命令查询的是从FFF0:0~FFF0:00FFH的范围。
打开cmd,键入debug
-d fff0:0 ff
……
FFF0:00F0
我们发现在00f5开始的内存单元存储着主板的生产日期。看红色标记。
(4)向内存从B800H开始的单元中填写数据,如:
-e
b810:0000
观察产生的现象;再改变填写的地址,观察产生的现象。
http://s8/bmiddle/006LW9dSzy7aXS5k7e737&690