实验1 用机器指令和汇编指令编程
一、实验内容和结论
1.教材实验1
(1)实验任务1
①用e命令将指令写入内存并修改CS:IP指向

用u命令反汇编写入的指令

用t命令单步调试

②用a命令将指令写入内存

寄存器清零,修改CS:IP指向

用t命令单步调试

(2)实验任务2
写入a命令


t命令执行16次



(3)实验任务3
内存内容查看


修改内存日期部分内容

说明:通过查看部分范围内的内存内容,发现转换为ASC码之后的数据中存在日期形式的内容。尝试通过e命令修改该部分内存的数据,发现没有效果,原因在于只读存储器只允许查看不允许修改。
(4)实验任务4
填写数据

在改变的位置填写数据

说明:在第一个位置填写数据时发现没有产生效果,原因在于该位置处于内存中的只读存储地址空间,不允许进行写入操作。在第二个位置填写数据时产生效果,说明可以在非只读存储地址空间中进行写入操作。
2.教材实验2
(1)实验任务1
使用e命令修改数据,并查看是否正确写入,并按要求用a命令写入程序指令

修改CS:IP指向

t命令单步调试




最后的栈内结果

实验前填写的结果为:
mov ax,[0] ;ax=5150
add ax,[2] ;ax=a4a2
mov bx,[4] ;bx=5554
add bx,[6] bx=acaa
push ax ;sp=00fe;修改的内存单元的地址是00fe,00ff 内容为a2,a4
push bx ;sp=oofc;修改的内存单元的地址是00fc,00fd 内容为aa,ac
pop ax ;sp=00fe;ax=acaa
pop bx ;sp=0100;bx=a4a2
push [4] ;sp=00ff;修改的内存单元的地址是00ff 内容为54
push [6] ;sp=00fe;修改的内存单元的地址是00fe 内容为56
根据debug中实际调试的结果比较,发现最后两个push操作的结果与实际不符,应该为:
push [4] ;sp=00fe;修改的内存单元的地址是00fe,00ff 内容为54,55
push [6] ;sp=00fc;修改的内存单元的地址是00fc,00fd 内容为56,57
错误原因:尽管push操作的对象是某一个内存单元不是寄存器,该内存单元只有一个字节,但是8086CPU的入栈和出栈操作都是以字为单位进行的。所以压入的数据为2字节而非1字节。
(2)实验任务2
写入程序并用t命令单步调试




说明:(1)第一行汇编指令功能为将数据2000写入寄存器ax中;第二行汇编指令功能为将寄存器ax中的数据写入段寄存器ss中,作为栈内存的栈顶的段地址;第三行汇编指令功能为将数据10写入寄存器sp,该寄存器存放栈顶的偏移地址,意味着该栈占用的空间大小为16字节,SS:SP始终指向栈顶。初始时的栈顶为2000:0,栈底为2000:f
(2)2000:0-2000:f内存空间首次发生变化是在执行mov ss,ax指令时,可以初步推测第11/12字节存储的当前IP寄存器的数据,第13/14字节存储的原来的SS寄存器的数据,第7/8字节有可能存储的是AX寄存器的数据,第15/16字节存储的数据还不能确定。根据网上查阅相关资料推测可能是在初始化时使用的mov ss,ax和mov sp,10指令会使得系统执行中断机制,第15/16字节存储的数据可能是中断机制中的某个寄存器的数据,并且创建一个栈时系统会将部分数据暂时存储在栈中,导致栈内空间在未进行操作时已经写入了数据。
二、实验总结
(1)在当前阶段一个基本的汇编语言使用流程大概为用e命令或a命令向内存中写入数据,用d命令查看是否正确写入,用u命令反汇编查看机器码的含义,用r命令查看和修改寄存器中的数据,用t命令单步调试执行指令。
(2)段地址+偏移地址的概念比较特殊,需要明确寄存器存储的是段地址还是偏移地址。
(3)用t命令执行指令前需要注意CS:IP是否指向了之后需要执行的命令的地址。
(4)对于内存中的只读部分,需要注意是无法修改的,在调试时要尽量避开此范围的内存空间。
(5)8086CPU的入栈和出栈操作都是以字为单位进行的。所以压入的数据为2字节而非1字节。并且要注意8086采用小端存储的方式,小地址存放低位数据。
(6)初始化一个栈时系统会在栈中暂时存放一些数据,包括当前IP寄存器的数据、原来的SS寄存器的数据、AX寄存器的数据、中断机制中的某个寄存器的数据。

浙公网安备 33010602011771号