1.内存中字的存储
3.1
16位的字存储在一个16位的寄存器:
高8位放高字节,低8位放低字节
16位的字在内存中需要两个连续字节存储:
低位字节存在低地址单元,高位字节存在高地址单元
字单元:由两个地址连续的内存单元组成,存放一个字型数据(16位)
2.用DS和[address]实现字的传送
3.2-3.4
在8086PC中,内存地址由段地址和偏移地址组成(段地址:偏移地址)
解决方案:DS和[address]配合
用DS寄存器存放要访问的数据的段地址
偏移地址用[…]形式直接给出
将10000H(1000:0)中的数据读到al中
mov bx,1000H
mov ds,bx
mov al,[0]
mov ax,[0]这句传送字型数据
mov [0],ax 将寄存器ax中的数据传送到内存
3.DS和数据段
3.5
对于8086PC机,可以根据需要将一组内存单元定义为一个段。
物理地址=段地址x16+偏移地址
将一组长度为N (N<64K )、地址连续、起始地址为16的倍数的内存单元当作专门存储数
据的内存空间,从而定义了一个数据段。
将哪段内存当作数据段,段地址如何定,由编程人员在编程时自行安排
add [0],[1] 非法语句
add ds,ax 非法语句
4.栈及栈操作的实现
3.6-3.10
栈是一种只能在一端进行插入或删除操作的数据结构。
栈有两个基本的操作︰入栈和出栈。
入栈︰将一个新的元素放到栈顶;出栈︰从栈顶取出一个元素。
push ax 将ax中的数据送入栈中
pop ax 从栈顶取出数据送入ax
(以字为单位对栈进行操作)
现今的CPU里都有栈的设计。
问题:
1、CPU如何知道一段内存空间被当作栈使用?
2、执行push和pop的时候,如何知道哪个单元是栈顶单元?
回答:
8086CPU中,有两个与栈相关的寄存器:
栈段寄存器SS:存放栈页的段地址
栈顶指针寄存器SP:存放栈顶的偏移地址
任意时刻,SS:SP指向栈顶元素
push ax的执行,由以下两步完成。
(1) SP-SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶;
(2)将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。
pop ax 的执行过程和push ax刚好相反,由以下两步完成。
(1)将SS:SP指向的内存单元处的数据送入ax 中;
(2) SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
8086CPU不保证对栈的操作不会超界。
8086CPU只知道栈顶在何处(由SS:SP指示),不知道程序安排的栈空间有多大。
5.关于"段"的总结
P69:段的综述
我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。这完全是我们自己的安排。
我们可以用一个段存放数据,将它定义为“数据段”;我们可以用一个段存放代码,将它定义为“代码段”:我们可以用一个段当作栈,将它定义为“栈段”。
我们可以这样安排,但若要让CPU按照我们的安排来访问这些段,就要:
对于数据段,将它的段地址放在DS中,用mov,add,sub等访问内存单元的指令时,CPU就将我们定义的数据段中的内容当作数据来访问;
对于代码段,将它的段地址放在CS中,将段中第一条指令的偏移地址放在IP中,这样CPU就将执行我们定义的代码段中的指令;
对于栈段,将它的段地址放在SS中,将栈顶单元的偏移地址放在SP中,这样CPU在需要进行栈操作的时候,比如执行push、pop指令等,就将我们定义的栈段当作栈空间来用。
一段内存,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么也不是。关键在于CPU中寄存器的设置,即CS、IP、SS、SP、DS的指向。