实验1 8086汇编指令编码和调试

一、实验结论:

1.实验任务2:PC机主板上的ROM中有一个生产时期,在内存FFF00H ~ FFFFFH的某几个单元中,请找到这个生产时

期,并试图修改它

在debug中,使用d命令查看生产日期:

实验1 8086汇编指令编码和调试

 

 使用e命令尝试修改(并查看修改后的结果):

实验1 8086汇编指令编码和调试

 

发现该日期并未修改,因为此操作是修改只读存储器中的内容,是无法实现的,只读存储器在内存的地址为C0000~ FFFFFH。

2.实验任务3:在debug中,使用e命令,向内存单元填写数据

显示如左上角

实验1 8086汇编指令编码和调试 

在debug中,使用f命令,向内存单元批量填写数据,显示在编辑器底部一行:

实验1 8086汇编指令编码和调试

 

 

 自己尝试改变内存地址和存入的数据,结果如下(显示出现在编辑器左侧中部的位置):

实验1 8086汇编指令编码和调试

 

 

3 .实验任务4:已知内存单元00201H ~ 00207H分别存放数据(如下图所示),00220H ~ 0022fH用作栈空间。

实验1 8086汇编指令编码和调试

在debug环境中,按顺序录入以下内容,单步跟踪调试,观察寄存器和内存空间00200H~00207H,以
及,栈空间00220 ~ 0022fH内容变化情况。记录实验结果。回答问题,验证和你的理论分析结果是否一
致。

实验1 8086汇编指令编码和调试

 

 

 (1)填空

-a
mov ax, 20
mov ds, ax
mov ss, ax
mov sp, 30
push [0] ; 执行后,寄存器(sp) = __002E__
push [2]   ; 执行后,寄存器(sp) = __002C__
push [4]   ; 执行后,寄存器(sp) = __002A__
push [6]   ; 执行后,寄存器(sp) = _0028___
pop [6]   ; 执行后,寄存器(sp) = _002A___
pop [4]   ; 执行后,寄存器(sp) = __002C__
pop [2]   ; 执行后,寄存器(sp) = __002E__
pop [0]   ; 执行后,寄存器(sp) = __0030__

  

(2)问题1:题目要求是把00220H ~ 0022fH用作栈空间。指令 mov ss, ax 和 mov sp, 30 执行后,栈顶的逻辑地址和物理地址分别是?

sp逻辑地址:0030

物理地址:0022fH

(3)问题2:单步调试到汇编指令 push [6] 执行结束, pop [6] 执行之前,使用 d 20:20 2f 查看此时栈空间数据,给出实验截图。

 实验1 8086汇编指令编码和调试

 

 

 

(4)问题3:汇编指令 pop [0] 执行结束后, pop [0] 指令执行结束后,使用d命令 d 20:0 7 查看此
时数据空间内的数据是否有变化。给出实验截图。

实验1 8086汇编指令编码和调试

 

 

 

(5)问题4:如果把最后四条指令改成截图中的顺序, pop [6] 指令执行结束后,使用d命令 d 20:0 7
查看此时数据空间内的数据是否有变化。给出实验截图 

实验1 8086汇编指令编码和调试

 

 

 4.实验任务5:在debug环境中,实践以下内容:

(1)问题1:使用t命令单步执行 mov ss, ax 时,是单步执行完这一条指令就暂停了吗?后面的指令 mov sp, 30 是什么时候执行的?

实验1 8086汇编指令编码和调试

 

  

 

 观察debug操作,发现单步执行mov ss, ax后,mov sp, 30就执行了,可以看到sp已经等于0030了。

(2)问题2:根据汇编指令,前三条指令执行后,00220H ~ 0022fH被设置为栈空间。并且,初始时,已通过f命令将初始栈空间全部填充为0。观察单步调试时,栈空间00220H ~ 0022fH内存单元值的变化,特

别是图示中黄色下划线表示出的数据值(073F:0108)。根据实验观察,尝试思考和分析原因。

我继续往下运行下去,再查看-d 20:20 2f

出现以下改变:

实验1 8086汇编指令编码和调试

 则可推出,栈空间内内存单元可以存储下一条指令的位置,即CS和IP寄存器的值。

5.实验任务6:使用任何一款文本编辑器,编写8086汇编程序源码

 

assume cs:code
code segment
start:
  mov cx, 10
  mov dl, '0'
s: mov ah, 2
  int 21h
  add dl, 1
  loop s
  mov ah, 4ch
  int 21h
code ends
end start

  

使用masm、link,汇编、链接,得到可执行文件task5.exe。运行程序。结合程序运行结果,理解程序
功能。

实验1 8086汇编指令编码和调试

 

 

masm、link命令在前(没有截到)
使用debug工具,调试task5.exe。根据第4章所学知识,任何可执行程序在执行时,都有一个引导程序
负责将其加载到内存,并将CPU控制权移交给它,也即将CS:IP指向可执行程序中第一条机器指令。在加
载可执行程序时,可执行前面512字节是程序段前缀PSP(Program Segment Prefix),用于记录程序一些
相关信息。
在debug中,使用d命令,查看task5.exe的程序段前缀,观察这256个字节的内容,验证前两个字节是
否是CD 20。

查看程序段前缀,前两个字节是CD 20:

实验1 8086汇编指令编码和调试

 

 6.实验任务7:下面程序的功能是,完成自身代码的自我复制:把 mov ax, 4c00h 之前的指令复制到内存0:200开始的连续的内存单元。补全程序,并在debug中调试验证,确认是否正确实现了复制要求。

 

assume cs:code
code segment
  mov ax, _____
  mov ds, ax
  mov ax, 0020h
  mov es, ax
  mov bx, 0
  mov cx, _____
s: mov al, [bx]
  mov es:[bx], al
  inc bx
  loop s
  mov ax, 4c00h
  int 21h
code ends
end

 可知是要将一定的代码段内容填入指定内存单元,ex(0020h):[bx]作为目标地址,则代码段地址作为源地址,我把第一个空填 cs;

先随便填一个cx,我先填0001h,在debug用u命令查看, mov ax, 4c00h指令停留在0017h,我有些不确定,决定尝试0015和0017;

 实验1 8086汇编指令编码和调试

 

 0015h并没有在目的地址存储完整的代码,

 实验1 8086汇编指令编码和调试

 

 0017则完整拷贝了,

实验1 8086汇编指令编码和调试

 

 最后补全后的代码为:

assume cs:code
code segment
  mov ax, cs
  mov ds, ax
  mov ax, 0020h
  mov es, ax
  mov bx, 0
  mov cx, 0017h
s: mov al, [bx]
  mov es:[bx], al
  inc bx
  loop s
  mov ax, 4c00h
  int 21h
code ends
end

  

二、实验总结

1、字节是固定的单位,等于八个二进制位,而字是计算机进行数据处理和运算的单位,用字长来表示大小,字长为若干个字节,不同的机器字长可能不同,在8086CPU中字长为16位,即两个字节,8086的几个数据寄存器是16位寄存器,每一个 16 位寄存器就可以当做 2 个独立的 8 位寄存器来使用了,所以在8086系统中,既可以将一个字存入寄存器内,也可以将字节存入,而且可以指定实在16进制的高二位还是第二位,在显示的时候,而在机器读取的时候从低位开始读,字的地址是低位的地址,我总是忘记,导致操作就不熟练甚至出现错误。

 

上一篇:汇编语言学习笔记(4)——汇编基本指令集


下一篇:nmap 的使用方法