第三章 寄存器(内存访问)
字单元的概念:字单元,即存放一个字型数据(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的指令时,下一条指令也紧跟着被执行。(产生这种现象的原因“传说中的‘中断机制’”)
- [kanwangxue] 如果是文字的,不是特别好啊,体力活,如果文字还加点动画,那就必须顶了。 01/15 01:10
- [kanwangxue] 必须顶啊。 01/15 00:54
- [ltoiii] 既然是实现loop功能,是否要考虑s和se标号? mov bx,offset s - offset 12/09 12:09
- [xiaoyao2012] 正确 11/01 15:33
- [xuer2016] 又找到2条被我忽视的地方: 1.PUSH 和 POP 针对字单元 2.POP 不能是CS 10/26 10:57
- [xuer2016] 学习了 我书写不规范,16进制字母前不加0,后面不加H,以后要注意了。。。 10/26 10:51
- [xuer2016] 来老师这学习下 10/26 10:31
- [youthangel] 不妙,CPU的利用率一下子就上去了。还好我的处理器不是太弱,35%左右的利用率。建议博主在修改一下 10/20 08:23
- [fpamc] 在我心里她就是我的女神。 10/02 08:58
- [newpeople] 你女朋友用得了简直就是一个女神…… 10/01 08:10
- [99998888] 请您指点一下如何找到会ASSEMBLER 语言的翻译,翻译成中文或英文。我的QQ ; 9097815 07/25 09:56
- [jeremy] 我觉得你学习的挺好,可以加你扣扣吗?我的469614823 08/07 14:46
- [zhangbo0805] 哈哈, 你好呀!很希望认识你呀!我发现你学习的积极性很高!正想向您学习呢! 07/31 23:31
- [tomato] 知道了,排得还挺满。 05/29 16:35
- [tomato] 现在学习情况怎么样?在做课设二还是什么? 05/29 10:41
- [tomato] 你的留言收到了。 05/05 23:51
- [fpamc] 开始学习c咯! 05/03 21:40
- [fpamc] 居然不能发博客了……! 04/22 21:03
- [tomato] 你相册中的游戏界面我看过了,非常好,界面很漂亮,很有创造力。博主,很有潜力。加油,一定能把这个游戏做 04/20 23:46
- [fpamc] 忙了半个月,不在家,没时间学习汇编。 但是在途中想到了一个有史以来最难的程序。对于刚学完9章的我。 04/13 20:56