汇编语言 实验1 用机器指令和汇编指令编程
实验1 用机器指令和汇编指令编程
一、实验目的
- 熟练掌握使用debug工具编写和调试x86汇编命令的方法
- 掌握8086CPU、寄存器、内存的基础知识
- 理解并掌握内存中多字节数据的存放:小端法
- 理解并掌握「栈」内存空间的特性和使用
- 掌握指令mov, add, sub, jmp, push, pop的基础用法
二、实验内容
- 教材实验1(P35)
- 教材实验2(P71)
为了便于验证实验结果,对「2. 实验任务」的(1)做如下两点调整: - 在使用 a 命令输入指令调试之前,先使用 e 命令将内存单元 0022:0 ~0022:7连续 8 个字
节数据修改为 50H, 51H, 52H, 53H, 54H, 55H, 56H, 57H - 将 P74 实验任务(1)中第1行的 mov ax, ffff → 改为 mov ax, 0022
三、实验结论
1. 教材实验1结论
实验任务(1)
- 采用e命令从0:200内存开始写入4行命令的机器码,并用d命令进行查看,可以看到写入成功。
由于t命令为执行CS:IP指向内存单元处命令,需要用r命令将CS:IP置为0:200。
![]()
- 再次使用r命令查看寄存器,可以看到CS:IP已经指向0:200,下一条命令与输入命令一致。
使用4次t命令,可以看到调试结果。
![]()
- 采用a命令直接输入指令。a命令在不带参数的情况下默认从CS:IP开始输入,因此不需要设置CS:IP的值。
![]()
- 用d命令可以看到输入成功。
![]()
- 再次使用r命令查看寄存器,可以看到下一条命令与输入的第一条命令一致。
使用4次t命令,可以看到调试结果。
![]()
实验任务(2)
- 采用a命令向2000:0输入指令。
![]()
- 使用d命令和u命令可以看到输入成功。
![]()
- 观察代码可以发现,该段代码为循环对ax做乘2运算,因此控制好运行次数即可得到2的8次方。
用r命令可以看到CS:IP不为2000:0,调整后开始调试:
![]()
- 重复8次add运算,最终得到2的8次方为1000H(即ax的值)
![]()
实验任务(3)
- 使用d命令查看内存FFFOOH~FFFFFH中的内容
![]()
- 可以从右侧的ASCII码预览中看到最后一行有01/01/92的字样,推测为生产日期。
用e命令常识对对应字节进行更改,并查看。
![]()
可以看到更改无效。
根据书1.15中的8086PC机内存地址空间分配可知,C0000H~FFFFFH为各类ROM空间,只读存储器无法写入内容,因此修改无效。
实验任务(4)
- 首先使用d命令查看B8100H的内容,可以很明显的看到输入的命令出现在了B810:0040的位置,这里就可以推测该段内存空间与显示有关。
向B8100H中写入要求数据,可以看到右上角出现图形。
![]()
- 更改数据,可以看到图形分为4块,每块的图案,背景色都在改变。
![]()
- 再向其他内存区域写入数据,可以看到不同区域也出现了不同图案。
![]()
根据书1.15中的8086PC机内存地址空间分配可知,A0000H~BFFFFH为显存空间,向该段内存空间写入的数据都会被输出到显示器上。并且各字节分别控制显示器的不同像素区域。
2. 教材实验2结论
实验任务(1)
- 使用 e 命令修改 内存单元0022:0~0022:f 中的数据,使用d命令可以看到正确输入
![]()
- 使用 a 命令输入的 p74 指令
![]()
- 截图记录:每一行指令单步调试(如单步调试步骤多,可分屏截图,但不要有遗漏)
![]()
![]()
此时使用d命令查看内存2200:00FC00FF,可以看到00FC00FF被修改为AA AC A2 A4。
![]()
继续调试。
![]()
再次使用d命令查看内存2200:00FC00FF,可以看到00FC00FF被修改为56 57 54 55。
![]()
- P74 中指令执行后各个寄存器填空结果如下,与调试结果一致。需要注意的是8086采用小端模式,高地址存储高位。
![]()
实验任务(2)
- 截图记录图 3.19 中使用 a命令输入的 7 行指令,使用 e 命令修改 2000:0~2000:f 的值,及修改后查看的部分
![]()
- 单步调试每一行汇编指令的截图。每一条指令单步调试后,都使用 d 命令查看2000:0~2000:f 的值。观察每一条指令执行后相关寄存器值的变化,及2000:0~2000:f 单元值的变化,并思考原因。
![]()
可以看到执行mov ss,ax后,下一条指令就是mov ax,3123,mov sp,10被自动执行了。Debug的T命令在执行修改寄存器SS的指令时,下一条指令也紧接着被执行。
同时,在执行完mov ss,ax和mov sp,10后,2000:0~2000:f开始出现数据,数据中出现了2000,与AX的值对应;0112与IP对应;073F与CS对应;01A3未知。
![]()
执行完mov ax,3123后,2000:0~2000:f中数据发生改变,AX,IP,CS的值均有出现,但所在未知发生变化;01A3未知。
![]()
执行完push ax后,3123入栈,AX,IP,CS的值上移。
![]()
![]()
执行完mov ax,3366后,栈中AX,IP,CS的对应发生改变。
![]()
执行完push ax后,3366入栈,AX,IP,CS的值上移。
以文字方式陈述:
3. 前3行汇编指令的功能,特别是,mov sp, 10意味着什么?初始时栈顶和栈底分别是?
mov ax,2000 //将2000送入ax
mov ss,ax //将ax送入ss 这两步为设置栈顶的段地址为2000
mov sp,10 //将10送入sp 即设置栈顶的偏移地址为10
此时栈顶栈为 2000:10;栈底为底2000:e
4. 基于单步调试观察到的变化,给出你对此的思考及可能原因分析。
很明显可以看到,栈中实际上存储了当前部分寄存器的值(01A3未知);而这些变化是在执行完mov ss,ax和mov sp,10后,即设定了栈的位置后出现的,可以推测是T命令调试时的暂存的程序现场,一开始未出现是因为栈不在设定的位置。
四、实验总结
- T命令为执行CS:IP指向的内存单元处的指令,而A命令可以向指定位置写入命令,如果需要执行该部分命令,需要更改CS和IP的取值。
- Debug的T命令在执行修改寄存器SS的指令时,下一条指令也紧接着被执行。
- Debug的在执行T命令时,实际上利用了CPU提供的单步中断功能,引发中断时会将部分寄存器内容,特别是CSIP(这两个寄存器指示了下一条指令的位置)入栈,以便恢复程序继续运行。
但是01A3并未在寄存器中出现,可以推测为某种指令或是指示入栈的程序现场的标志。
根据这一条可以推测,Debug的T命令在执行修改寄存器SS的指令时,为了保证入栈的程序现场不出现混乱,默认一起执行下一条指令(一般为对SP的修改)。 - 根据8086CPU内存地址空间分配的情况可以看到,除了RAM外,还有显存区域和ROM区。
向显存区域写入数据会改变图像的显示情况,不同的地址控制不同像素区域,存储的数据控制对应区域显示的符号和底色。
ROM为只读存储器,不可被修改,一般存储不可被更改的关键信息。
![]()































浙公网安备 33010602011771号