汇编网首页登录博客注册
fpamc的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态

[2012-02-21 14:55] 第三章笔记

第三章 寄存器(内存访问)
字单元的概念:字单元,即存放一个字型数据(16)的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。

MOV指令中的[]说明操作对象是一个内存单元,[]中的内容是这个内存单元的偏移地址。
用MOV指令访问内存单元,可以在MOV指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中。
在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应。

栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。栈的这种操作规则被称为:LIFO(Last In First Out,后进先出。)
8086CPU的入栈和出栈操作都是以字为单位进行的。
栈顶的段地址存放在SS中,偏移地址存放在SP中。任意时刻,SS:SP指向栈顶元素。

任意时刻,SS:SP指向栈顶元素,当栈为空的时候,栈中没有元素,也就不存在栈顶元素,所以SS:SP只能指向栈的最底部单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址+2。

出栈后,SS:SP指向新的栈顶X,pop操作前的栈顶元素,X-2处的数据依然存在,但是它已不在栈中。当再次执行push等入栈指令后,SS:SP移至x-2,并在里面写入新的数据,它将被覆盖。
栈顶超界的问题:
8086CPU只记录栈顶,栈空间大小我们要自己管理。
当执行push指令后,栈顶超出了栈空间,栈空间外的数据将被覆盖。
当执行pop指令后,栈顶超出了栈空间,此后,如果再执行push指令,超出部分的空间的数据将被覆盖。

我们在编程的时候要自己操心栈顶超界的问题,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;执行出栈操作的时候也要注意,以防栈空的时候继续出栈而导致的超界。

8086CPU的工作机理,只考虑当前的情况:
        当前栈顶在何处;(SS:SP)
        当前要执行的指令是哪一条。(CS:IP)


几条栈操作指令:push、pop
几种形式:push 寄存器
               段寄存器
               内存单元
          pop 寄存器
              段寄存器
              内存单元
指令可以指定段寄存器作为操作数,注意pop绝对不能使用代码段(CS)寄存器。

用栈来暂存以后需要恢复的寄存器中的内容时,出栈的顺序要和入栈的顺序相反。

执行push时,CPU的两步操作是:先改变SP,后向SS:SP处传送。
执行pop时,CPU的两步操作是:先读取SS:SP处的数据,后改变SP。
注意:push、pop等栈操作指令,修改的只是SP。所以说,栈顶的变化范围最大为:0~FFFFH。

SS、SP指示栈顶;改变SP后写内存的入栈指令;读内存后改变SP的出栈指令。这就是8086CPU提供了栈操作机制。

push指令的执行步骤:①SP=SP-2;②向SS:SP指向的字单元中送入数据。
pop指令的执行步骤:①从SS:SP指向的字单元中读取数据;②SP=SP+2。

Push、pop实质上是一种内存传送指令。
Push、pop等指令在执行的时候只修改SP,所以栈顶的变化范围是0~FFFFH,从栈空时候的SP=0,一直压栈,直到栈满时SP=0;如果再次压栈,栈顶将环绕,覆盖了原来栈中的内容。所以一个栈段的容量最大为64KB。

我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。这完全是我们自己的安排。
1)我们可以用一个段存放数据,将它定义为“数据段”;
对于数据段,将它的段地址放在DS中,用mov、add、sub等访问内存单元的指令时,CPU就将我们定义的数据段中的内容当做数据来访问;
2)我们可以用一个段存放代码,将它定义为“代码段”;
对于代码段,将它的段地址放在CS中。将段中第一条指令的偏移地址放在IP中,这样CPU就将执行我们定义的代码段中的指令;
3)我们可以用一个段当做栈,将它定义为“栈段”;
对于栈段,将它的段地址放在SS中,将栈顶单元的偏移地址放在SP中,这样的CPU在需要进行栈操作的时候,比如执行push、pop指令等,就将我们定义的栈段当做栈空间来用。

一段内存,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么都不是。关键在于CPU中寄存器的设置,即CS、IP,SS、SP,DS的指向。

Debug中一些命令的用法:
关于D命令。
①直接“d”。查看预设的内存单元的内容。
当之前被指定查看某一内存单元的内容时,直接“d”将会显示后续内存单元的内容。
②“d 段地址:偏移地址”。将显示出由指定地址开始的后续128个字节的内容。
③“d 段地址:偏移地址~偏移地址”
④“d 段寄存器:偏移地址”用段寄存器表示内存单元的段地址。
在E、A、U命令中也可以同D命令一样,用段寄存器表示内存单元的段地址。

Debug在处理其D命令的程序段中,必须有将段地址送入段寄存器(=ds)的代码。
Debug的T命令在执行修改寄存器SS的指令时,下一条指令也紧跟着被执行。(产生这种现象的原因“传说中的‘中断机制’”)
评论次数(1)  |  浏览次数(689)  |  类型(汇编笔记) |  收藏此文  | 

[  xuer2016   发表于  2012-10-26 10:57  ]

又找到2条被我忽视的地方:
1.PUSH 和 POP 针对字单元
2.POP 不能是CS

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码