汇编实验二

 

第一题:

第一步:打入书上的代码至当前cs:ip所指向的地址段(如图):

 

第二步:

先执行前五条:即给寄存器ds,ss,sp赋值(如图):

 

然后继续逐条执行:

 

执行以下指令后寄存器以及内存单元中数据的变化:

Mov ax,[0]                           ax=5bea

Add ax,[2]                            ax=5cca

Mov bx,[4                            bx=30f0

Add bx,[6]                            bx=6029

Push ax                                sp=00fe修改的内存单元的地址是2200:00fe2200:00ff;内容是5cca

Push bx                                sp=00fc修改的内存单元的地址是2200:00fc2000:00fd;内容是6029

Pop ax                                  sp=00fe ax=6029

Pop bx                                  sp=0100 bx=5cca

Push [4]                                sp=00fe修改的内存单元的地址是2200:00fe2200:00ff;内容是30f0

Push [6]                               sp=00fc修改的内存单元的地址是2200:00fc2200:00fd;内容是2f39

注:在执行语句mov ss,ax后ip的值没有从0108变为010A而是变成了010D即ip的值直接加了五,说明mov ss,ax和mov  sp,0100是一起执行的。并且这几条语句是通过栈的先入后出的机制来实现ax和bx值的互换,过程是:准备好要换的两个数据a、b,分别赋值给ax,bx,然后将ax,bx中的值先后压栈,弹栈的时候需要注意,此时栈顶指针ss:sp所指向的字数据是后入栈的bx中所存储的数据,所以要实现ax,bx中值的互换就需要弹栈并将弹出的字数据值赋值给ax(即pop ax),然后在弹栈将下面的字数据赋值给bx(pop bx)。

第二题:

对书上的实验3.19过程观察: 发现执行了3条语句,它们分别是:

mov ax,2000

mov ss,ax

mov sp,10(没有在单步调试中出现,因为它和mov ss,ax一起执行了)

所以并未进行ax的赋值操作和压栈操作,所以内存段2000:0~2000:f中内存单元的值的变化并不是因为压栈所造成的。又并未进行人为的改变内存单元中值的操作,唯一进行一系列操作就是改变了ss和sp中得值即“声明”了一段空的栈空间,此时sp指向的是这个栈第一个字数据的偏移地址加上2的位置。所以不做压栈的操作是不可能改变栈空间里的值的。

经过寄存器中的值和栈中的值的对照观察,以及翻阅课本,发现:在单步调试的过程中,计算机可能进行了压栈操作,这个压栈操作是为了使语句能够运行下去而进行的,而这些入栈的操作被称为中断过程课本12.4),同时又发现(如图):

 

在偏移地址为BH偏移地址为DH这两个地址单元中所存放的字数据恰好为当前ip和cs里的数据(0108H和0B39H),又考虑到入栈的先后问题,cs比ip先入栈,而最先入栈的字数据9D05经查阅为标志寄存器中的值先入栈所以便发现在单步执行语句的过程中,先将标志寄存器的值入栈,然后再将cs的值入栈,再将ip的值入栈,至于偏移地址为6处所存放的猜测可能是ax中要存放的值2000H。

总结:本次试验主要训练了栈段寄存器ss和栈指针寄存器sp的赋值(即声明一个你要用的(ss,sp中本来就已经又数值了)栈空间)、熟悉了利用数据段寄存器访问内存单元、练习了压栈push和弹栈pop操作以及压栈和弹栈具体在栈空间是如何实现的(压栈:sp先减2在将字数据按小端发放入存储单元,弹栈:先将ss:sp当前所指向的地址中的字数据拿出来赋值给指定的寄存器再将sp+2),并且一个栈为空的条件即为sp==栈中只有一个字数据时这个字数据的偏移地址+2。又重新认识了CPU,认识到CPU对指令的执行过程并不只是从cs:ip直接将数据拿过来那么简单。

原文地址:https://www.cnblogs.com/tomori/p/9838947.html