1、内存中字的存储
低位对应低地址位,高位对应高地址位;
结论:任何两个地址连续的内存单元,N和N+1号单元,可以将他们看作2个内存单元,也可以看成一个地址为N的字单元的高位字节单元和低位字节单元。
2、DS和地址
在8086PC中,内存地址由段地址和偏移地址组成;
8086CPU中,有一个DS寄存器,通常用来存放要访问数据的段地址;
执行指令时,8086CPU自动取DS中的数据为内存单元的段地址。
8086CPU不支持将数据直接送入段寄存器的操作,DS是一个段寄存器(硬件设计的问题);
所以mov ds,1000H是非法的。
数据怎样给段寄存器:数据---->通用寄存器---->段寄存器
字的传送:
因为8086CPU是16位的结构,有16根数据线,所以,可以一次性传送16位的数据,可以理解为一次传送一个字。
3、mov、add、sub指令
(1)、mov指令的几种形式
mov 寄存器, 数据 :mov ax, 6
mov 寄存器, 寄存器 :mov bx, ax
mov 寄存器, 内存单元 :mov ax, [0](偏移地址)
mov 内存单元, 寄存器 :mov [0], ax //将ax寄存器中的值,放到内存单元段地址是ds,在结合我们给出的偏移地址[0],找到对应的内存,最后把这个值放进去;
mov 段寄存器, 寄存器 :mov ds, ax
例如:
验证一下有没有mov 寄存器,段寄存器
(2)、add和sub指令同mov一样,都有2个操作对象,进行对数值的加/减运算;
4、数据段
在8086PC机中,我们可以根据需要将一组内存单元定义为一个段(可以是代码段、数据段等)。
可以自己将一组长度为N(N<64K)、地址连续、起始地址为16的倍数的单元用来存储数据的内存空间,从而定义了一个数据段。
怎么数据段中的数据?
:将一段内存当作数据段,是我们在编程时的一种安排,用ds存放数据段的段地址,在根据情况写出偏移地址就可以访问了;
5、栈
(1)、栈:具有特殊的访问方式的存储空间,特殊性:先进后出;
栈的2个基本操作:入栈(PUSH)和出栈(POP);8086CPU的入栈/出栈都是以字为单位进行的;
CPU一般都提供了栈这个机制;8086CPU提供相关的指令来以栈的方式访问内存空间。
(2)、push ax :将寄存器ax中的数据送入栈中;
push ax :从栈顶取出数据送入ax中。
(3)、CPU如何知道一段内存空间被当做栈使用?
:寄存器CS和IP中存放着当前指令的段地址和偏移地址;
:8086CPU中,有2个寄存器,SS(段寄存器):存放栈顶的段地址;SP(寄存器):存放栈顶的偏移地址
:任意时刻,SS和SP指向栈顶元素(在进行push/pop的过程中,SS:SP将会不断的变化,始终指向栈顶元素)
(4)、换个角度来看看SS:SP
任意时刻,SS:SP指向栈顶元素,当栈为空的时候,栈中没有元素,也就不存在栈顶元素,所以此时,SS:SP只能指向栈的最底部单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址+2,栈最底部字单元的地址为1000:000E,所以栈空时,SP=0010H。
6、栈顶越界
SS和SP只记录了栈顶的地址,栈顶越界是危险的。
:因为在栈之外的空间里可能存放了具有其他用途的数据、代码等,这些数据、代码可能是我们自己程序中的,也可能是别的程序中的。
CPU只知道要执行的指令在何处,但是不知道要执行的指令有多少。
8086CPU的工作机理:当前栈顶在何处,当前要执行的指令是哪一条;
结论:在编程时自己小心对越界的操作问题。
7、push和pop
(1)、指令的格式:
i>、push 寄存器 pop 寄存器
ii>、push 内存单元 :将一个内存单元的字入栈; push [0]
pop 内存单元 :用一个内存单元接受出栈的数据; pop [2]
(2)、push、pop等栈操作指令,修改的只是SP,可以得知:栈顶的变化范围最大为:0-FFFFH。
8、栈的综述
(1)、8086CPU提供栈操作机制,方案:SS、SP中分别存放栈顶的段地址和偏移地址;
(2)、任意时刻,SS:SP指向栈顶元素;
(3)、8086CPU只记录栈顶,栈空间的大小我们要自己管理;
(4)、寄存器出栈顺序和入栈顺序是相反的。
9、段
将一段内存定义为一个段,有段地址,有偏移地址访问段内的单元,这些都是我们自己安排的。CPU将内存看成一个逻辑单元,我们看的是一个一个的段;
我们可以用一个段来存放数据,将其定义为"数据段";
我们可以用一个段来存放代码,将其定义为"代码段";
我们可以用一个段当作栈,将其定义为"栈段";
我们可以这样安排,但要让CPU按照我们的安排来访问这些段,就要 :
(1)、对于数据段,将它的段地址放在DS中,用mov、add、sub访问内存单元指令时,CPU就将我们定义的数据段中的内容当做数据段来访问;
(2)、对于代码段,将它的段地址放在CS中,将段中的第一条偏移地址放在IP中,这样CPU就将执行我们定义的代码段中的指令;
(3)、对于栈段,将它的段地址放在SS中,栈顶单元的偏移地址放到SP中,CPU在执行push、pop等指令时,就将我们定义的栈段当做栈空间来用;
可以得出:不管我们怎么安排,CPU将内存中的某段内存当做代码,是因为CS:IP指向了那里;CPU将某段内存当做栈,是因为SS:IP指向了那里。
10、总结
一段内存,可以是代码、数据、栈中的任意空间,也可以什么都不是,关键在于CPU中寄存器的设置,即:CS、IP、SS、SP、DS的指向。