汇编学习笔记:寄存器(内存访问)

==============寄存器(内存访问)===========================
CPU用16位寄存器存储一个字,高八位存放高位字节,低八位存放低位字节。
在内存中存储时,内存单元是字节单元(一个单元存放一个字节,即8位),所以使用两个连续的内存单元来存放。
字在内存中的存储,重点解释“字单元”的概念:
字单元,即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。
高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。
比如:用0,1两个内存单元存放20000(4E20H),0号地址是低内存单元,存放20;1号地址是高内存单元,存放4E;
总结:任何两个连续的内存单元,N号单元和N+1号单元,可以将它们看成两个内存单元,也可以看成一个地址为N的字单元中的高位字节单元和低位字节单元。


DS和[address]:


mov ax,1000H
mov ds,ax
mov al,[0]


上面的3条指令是将10000H(1000:0000)内存单元中的数据读到寄存器al中
指令详解:前两条指令是将要访问内存单元的段地址放入ds中,最后一条指令中的[...]表示内存单元的偏移地址,它的段地址默认存放在ds中,
执行指令时,8086CPU自动取ds中的数据作为内存单元的段地址。
所以最后一条指令执行的操作是将从10000H(1000:0000)内存单元中取出数据并放入al中。


那么为什么不直接将段地址1000H放入段寄存器ds中呢?这是因为8086CPU设计的问题,
[不支持将数据直接放入段寄存器中。]所以我们才用ax寄存器作为中转进行数据传输。


段寄存器CS跟DS的区别:
cs是值cpu执行的当前指令的段地址,ds是数据开始的段地址。
通俗来讲,CS是告诉CPU,去哪个位置找内容当成指令去执行,
DS是告诉CPU,去哪个位置找内容当成数据被使用,用它们的扩展名便可以知晓区别:
datasegment=ds
codesegment=cs
CPU要执行CS中的指令 指令用到的数据可能就存放在DS中。
你可以把数据放到CS中,但是CPU并不把它当成数据来使用,你也可以把指令放到DS中,但是CPU根本不去DS里读指令。
补充:段寄存器是不可以用在算术运算指令中的!

栈【先进后出FILO】:
栈是一种具有特殊访问方式的存储空间,它的特殊性在于,最先进入这个空间的数据,最后出去。


8086CPU提供入栈和出栈指令,最基本的两个是PUSH(入栈)和POP(出栈)。
比如push ax表示将寄存器ax中的数据送入栈中,pop ax表示从栈顶取出数据送入ax。
8086CPU的入栈和出栈操作都是以字为单位进行的,也就是说每次操作两个Byte(字节)。
字型数据用两个单元存放,高地址单元存放高八位,低地址单元存放低八位。


8086CPU中有两个寄存器,段寄存器SS和寄存器SP
段寄存器SS:存放栈顶的段地址。
寄存器SP:存放栈顶的偏移地址。
任意时刻,SS:SP指向栈顶元素


Push ax 的执行步骤:
1). SP=SP-2,SS:SP指向当前栈顶前面的内存单元,以当前栈顶前面的内存单元作为新的栈顶;

2). 将ax中的内容送入SS:SP指向的内存单元处,SS:SP指向新的栈顶。





段的综述:
我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。


我们可以用一个段存放数据,将它定义为“数据段”;ds,[address]
我们可以用一个段存放代码,将它定义为“代码段”;cs:ip
我们可以用一个段当做栈,将它定义为“栈段”。    ss:sp


我们可以这样安排,但CPU就要按照如下方式来访问这些段:


对于数据段,将它的段地址存放在DS中,用mov,add,sub等指令访问内存单元时,CPU就将我们定义的数据段中的内容当做数据来访问。
对于代码段,将它的段地址存放在CS中,将段中第一条指令的偏移地址存放在IP中,这样CPU就将执行我们定义的代码段中的指令。
对于栈段,将它的段地址存放在SS中,将栈顶单元的偏移地址存放在SP中,这样CPU在需要进行栈操作的时候,比如push,pop指令等,就将我们定义的栈段当做栈空间来使用。


可见,不管我们如可安排,CPU将内存中的某段内容当做代码,是因为CS:IP指向了那里;
CPU将某段内存当做栈,是因为SS:IP指向了那里。
posted @ 2013-01-07 06:24  java程序员填空  阅读(309)  评论(0编辑  收藏  举报