实验1 用机器指令和汇编指令编程
实验1 用机器指令和汇编指令编程
一、实验目的
1. 熟练掌握使用debug工具编写和调试x86汇编命令的方法
2. 掌握8086CPU、寄存器、内存的基础知识
3. 理解并掌握内存中多字节数据的存放:小端法
4. 理解并掌握「栈」内存空间的特性和使用
5. 掌握指令mov, add, sub, jmp, push, pop的基础用法
二、实验内容
1. 教材实验1(P35)
2. 教材实验2(P71)
三、实验结论
1. 教材实验1结论,教材实验1中「2. 实验任务」(P45)
实验任务(1)
机器码数据较多,只用前4行实验。
①、a命令
使用a命令输入指令,修改cs:ip所指地址,修改之后使用t命令单步调试,结果如图:

②、e命令:
输入机器码之后也需要注意cs:ip是否指向当前机器码存储地址,修改后同样使用t命令单步调试,
结果如图:

使用a命令输入汇编指令/e命令输入机器码对应的寄存器值变化:
| 机器码 | 汇编指令 | 寄存器变化 |
| b8 20 4e | mov ax,4e20H | ax = 4e20H |
| 05 16 14 | add ax,1416H | ax = 6236H |
| bb 00 20 | mov bx,2000H | bx = 2000H |
| 01 d8 | add ax,bx | ax = 8236H |
实验任务(2)
使用a命令将指令输入到命令来窗口中,并修改cs:ip的值,

使用命令t单步调试,结果如图:

继续使用t单步执行,执行到2的8次方,结如图:

这三行汇编代码实现的是计算2的n次方,结果存放在寄存器ax中,由汇编指令jmp 2000:0003实现跳转,
执行之后跳转回20003,该地址段存储指令(add ax,ax),以此循环实现计算2的n次方,并将值存储在ax上。
实验任务(3)
使用d命令从段地址fff00,偏移量为0开始查找,在偏移量为f0的内存单元中存在字符02/27/20
结果如图:

更改该行数据,改变日期,将日期改为12/06/20(数字0~9 对应的ASCII码值 30~39)

以上均在虚拟机win7系统中的doc命令窗口使用debug进行实验,
使用docbox查找到日期为:01/01/20,同时在docbox中无法修改该段地址中的数据,结果如下:

尝试使用e命令修改该段数据,再次查看时发现该段数据未发生改变。
实验任务(4)
使用e命令修改指定地址内的数据,如图:

按下回车之后可以贯彻到命令窗口上出现图标,改变地址:-e b820:0000 34 56 78 5d 4f 34 21 09,
结果如图:

改变值:-e b820:0000 01 01 02 02 03 03 04 04,
结果如图:

在修改数据之后命令窗口上会立即做出响应出现特殊图标,说明修改的该段地址是显存地址。对于8080cpu而言,
地址A000H~BFFFFH的8KB空间为显存地址空间。cpu向该段内存地址输入数据,数据将会被写入显存中,然后会被显卡输出到显示器上。
2. 教材实验2结论
教材实验2中「2. 实验任务」(P74)
实验任务(1)
① 截图记录:使用 e 命令修改 内存单元0022:0~0022:f 中的数据,及修改后查看是否正确写入的操作
② 截图记录:使用 a 命令输入的 p74 指令
③ 截图记录:每一行指令单步调试(如单步调试步骤多,可分屏截图,但不要有遗漏)
④ P74 中指令执行后各个寄存器填空结果,以在文档中手工标注或手机拍照截图方式复制在文档中。
对于③单步调试的观察,与理论上分析的结果进行比较,检验是否一致。如不一致,分析原因。
在使用 a 命令输入指令调试之前,先使用 e 命令将内存单元 0022:0 ~0022:7连续 8 个字节数据修改为 50H, 51H, 52H, 53H, 54H, 55H, 56H, 57H
将 P74 实验任务(1)中第1行的 mov ax, ffff → 改为 mov ax, 0022。
修改内存单元数据,如图:

使用a命令输入指令,如图:

使用t命令单步执行,如图:

中间调试步骤省略......

执行指令对应的寄存器之变化如下:
|
mov ax,0022
实验结果于理论结果相同 |
观察其中寄存器sp的值的变化,使用push命令执行入栈操作,sp值(段地址偏移量)减2;在执行pop命令执行出栈操作,sp(段地址偏移量)值加2。
在使用t命令单步执行时,发现mov sp,0100在mov ss,ax后直接执行了,再使用t命令执行的是mov ax,[0]
实验任务(2)
① 截图记录图 3.19 中使用 a命令输入的 7 行指令,使用 e 命令修改 2000:0~2000:f 的值,及修改后查看的部分
② 单步调试每一行汇编指令的截图。每一条指令单步调试后,都使用 d 命令查看2000:0~2000:f 的值。
观察每一条指令执行后相关寄存器值的变化,及 2000:0~2000:f 单元值的变化,并思考原因。
以文字方式陈述:
① 前3行汇编指令的功能,特别是,mov sp, 10意味着什么?初始时栈顶和栈底分别是?
② 基于单步调试观察到的变化,给出你对此的思考及可能原因分析。
使用a命令输入指令,使用t命令单步调试,并用d命令查看2000:0~2000:f 的值的变化


① 前3行汇编指令的功能,特别是,mov sp, 10意味着什么?初始时栈顶和栈底分别是?
mov ax,2000 将值2200存入寄存ax
mov ss,ax 是将寄存器ax'的值存入到阶段地址寄存器ss中
mov sp,10 是移动指针指向该段地址的偏移量为0010的内存空间
ax,ss,sp均为寄存器,ss为段地址寄存器,ss:sp指向栈顶元素(可以理解为指针),mov sp, 10意味着将栈顶指针移到内存地址为20010的内存单元;
初始时栈顶ss:sp为2000:0010,栈底ss:sp为:2000:0010(栈底地址错误:应为2000:000E)
② 基于单步调试观察到的变化,给出你对此的思考及可能原因分析。
发现:栈在使用push指令存入数据之前在执行mov指令后栈中的数据就会发生改变,在执行栈相关操作之前会将寄存器存
储的值存储到栈中指定位置上(如图),随着栈相关操作的进行,数据会存入栈中,先前存放寄存器的值的地址将会被占用,用来存放入栈的值。

四、实验总结
1、mov指令:寄存器使用mov赋值,注意段地址寄存器不可以使用mov 传入立即数来更改段地址,应使先将立即数存
入寄存器中, 再使用mov存入段地址寄存器。(mov 段地址寄存器 , 寄存器)
段地址寄存器:ss,cs,ds 注意:ip(指令指针寄存器)不能直接传值;同时mov指令的两个操作数不能同时
为内存单元(两个内存单元之间不能直接存值)
add指令:add指令对的操作数不能同时为内存单元.
2、8086PC机内存地址空间分配:00000~9FFFF为主存储器地址空间
A0000~BFFFF现存地址空间
C0000~FFFFF为给类ROM地址空间
3、栈:一个栈段的容量最大为64KB(2^16),在使用栈时,栈的段地址ss的值不会变,改变的时寄存器sp的值sp最
大的移动范围(0~FFFFH)限制栈的容量为64KB
ss:sp理解为栈顶指针,使用push指令和pop指令时寄存器sp的变化:
使用push命令时:寄存器sp向减2,再将值存入内存单元中;使用pop指令时,先取出值,再将寄存器sp加2
使用push指令存入值,使用pop指令取值之后栈内存单元中存的值任然存在,不会因为pop指令的执行而清除。
查看栈对应的段地址内存单元中的数据可以发现:入栈的数据数值高位存放在地址的高位,数值的低位存放在地址的低位(采用的是小端法)
浙公网安备 33010602011771号