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

一、实验目的

  1. 掌握8086CPU、寄存器、内存(包括栈空间)的基础知识
  2. 掌握汇编源程序组成与结构
  3. 理解和掌握寄存器间接寻址方式
  4. 掌握汇编指令mov, add, sub, jmp, push, pop,loop的用法,理解高级语言的表达和抽象机制
  5. 熟练掌握使用debug工具编写和调试x86汇编命令的方法
  6. 掌握汇编语言源程序编写→汇编→链接→调试的工具和方法

二、实验结论

1. 实验任务1

2. 实验任务2

d命令查看生产日期:

img

e命令修改生产日期:

img

结论:不能修改,该段内存空间为ROM只读存储器,不能改写

3. 实验任务3

e命令修改内存单元: img

数据写入显存中,直接显示在屏幕上(爱心)

f命令批量填充内存单元: img

修改内存单元和数据: img

img

修改内存单元显示的位置变化,修改数据显示的符号变化

4. 实验任务4

  • 填空
-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
  • 回答问题

问题1:

逻辑地址:0020:30H

物理地址:0230H

问题2:

push [6]执行完时的栈空间:

问题3:

pop [0]执行完的数据空间:

1634962015149

数据无变化

问题4:

pop命令改变顺序后,执行完时的数据:

1634962786499

数据有变化

5. 实验任务5

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

并不是,t命令单步执行mov ss,ax后没有暂停,连同后面的mov sp,30也执行了。

查阅资料发现对ss和sp的设置是原子操作,t命令单步执行设置ss的指令时会把两条指令都执行完再暂停。

原因:

ss:sp联合指向栈顶,对它们的设置应该是一个原子操作。假如在mov ss,ax后响应中断,那么要将标志寄存器,cs,ip压栈,但此刻sp设置尚未完成,就会出现error。所以ss设置完成后,不响应中断,下一条指令自动执行,两条指令执行完的时候才响应单步中断,转入相应的中断处理程序,显示相应的信息

问题2: 根据汇编指令,前三条指令执行后,00220H ~ 0022fH被设置为栈空间。并且,初始时,已通过f命令将初始栈空间全部填充为0。观察单步调试时,栈空间00220H ~ 0022fH内存单元值的变化,特别是图示中黄色下划线表示出的数据值。根据实验观察,尝试思考和分析原因。

t命令执行前三条指令后,可以发现没执行压栈指令但栈空间的值产生变化。

原因是使用t命令单步执行时程序产生中断,为响应中断,需要先保存程序的执行状态,将标志寄存器,cs,ip压栈。可以看出此时栈顶的两个内存单元分别保存当前的ip和cs的值。

6. 实验任务6

程序源码:

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:

1634965416797

link:

1634965461652

执行task6.exe:

1634965498155

debug查看PSP:

1634965690105

前两个字节是CD

7. 实验任务7

补全程序:

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

cs中存放程序的段地址,通过ax传入ds中,后面可直接用loop和[idata]访问程序各行代码;

mov ax,4c00h前面的指令总长度为17h个字节,循环中每次复制一个字节,需要循环17h次;

debug:

1635046036514

g命令执行到mov ax,4c00h时,已经把源程序代码复制到了目标空间

三、实验总结

  1. 通过debug调试加深了对指令执行的底层逻辑的理解;
  2. 对ss和sp的设置为原子操作,中间出现中断也会执行完整个过程再响应中断(原因);
  3. 程序响应中断时,为了处理完中断能恢复现场,会先将标志寄存器,cs,ip压栈。