实验结论
(1)
书上任务1的填空:
首先,使用 e 命令将内存单元 0021:0 ~0021:7 连续 8 个字节数据修改为 30H, 31H, 32H, 33H,34H,35H,36H,37H
然后用a命令输入程序段
然后蠢蠢的我检查了一下cs和ip的值,结果发现就是该程序段的起始地址,emmmm……好吧,貌似程序段的起始地址就是当前cs和ip的指向(忘却了=。=)
然后使用t命令单步执行我们的程序段
(小端法,所以实际存放的为6462H和6C6AH)
经检验,实验结果和之前填空的结果一致,perfect!
(2)
用a命令输入程序段,然后用e命令修改从2000:0开始的16个内存单元的值,再使用d命令查看修改结果,然后用r命令查看各寄存器的初始值
然后我们用t命令进行单步执行,并且每执行完一步就使用d命令查看一次2000:0~2000:f的值
前三行的汇编指令的功能分别为:将2000H送入ax寄存器;将ax的值送入ss栈段地址寄存器;将10H送入sp栈偏移地址寄存器。ss:sp指向栈顶,即初始栈顶为2000:10,栈底为初始栈顶-2即2000:E。
可以发现,在执行完ss,ax后,2000:0~2000:f内的值发生了变化,且下一步执行的代码变成了ax,3123,但是sp的值变成了10,说明sp,10悄悄地被执行了。继续观察我们可以发现2000:a的值变成了ip的值,2000:c中的值变成了cs的值(虽然也和ds和es的值相同,但结合我目前的知识,认为cs和ip是相匹配的,姑且认为是cs的值),2000:6的值变成了ax的值(后面将ax的值变为了3123后2000:6的值也变成了3123所以我认为这里的值即是ax的值)。也就是说,ax,cs,ip的值,在该栈中都有存储,这样做的目的是什么,根据我目前掌握的知识还不得而知,还需要进行进一步的学习才能知晓。我上网查找了资料“ 为什么,在讲内中断这章时,你就明白了。t命令实际是引发了单步中断,执行中断例程时,CPU会将一些中断例程使用的的寄存器变量自动压栈到栈中,此例中就包括了上述的寄存器变量的值。”
执行完push,ax后可以看到,ax中的值即3123入栈,此时栈顶和栈底相同为2000:E,因为有数据入栈,可以看到,前面的数据被往前“顶”了两个单元,然后3366入栈,前面的数据又被向前“顶”了两个单元,显然这两个入栈操作后,ss:sp都正确指向了栈顶。
执行完毕
总结与体会
了解了栈的机制,对于数据的入栈和出栈有了一定的实践上的认识,初步认识和了解了ss和sp寄存器,但是对于栈的基本操作中的一些细节还不是很明了,比如中断啥的,还需要通过进一步的学习来了解