第三章 寄存器(内存访问)
3.1 内存中字的存储
字的概念:字单元,既存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成;高地址内存单元中存放字型数据的高字节,低地址内存单元中存放字型数据的低位字节。比如一个字由2、3两个内存单元组成,则这个字单元的起始地址为2,可以看成是2地址字单元。
问题3.1:
(1)0地址的字节型数据为:20H
(2)0地址的字型数据为:4E20H
(3)2地址的字节型数据为:12H
(4)2地址的字型数据为:0012H
(5)1地址的字型数据为:124EH
3.2 DS和【address】
8086CPU中,内存单元地址由段地址和偏移地址组成。ds用来存放访问数据的段地址,ds 不能直接由数据直接存入,必须由一个寄存器的内容送到ds里,
偏移地址由“[...]”中的数据表示内存单元的偏移地址。例如:
问题 3.2:将al数据送入10000H中。
3.3 字的传送
因为8086CPU是16位结构,一次可传16位数据,也就是一个字型数据。
问题3.3和问题3.4::跟问题3.1差不多让我们更加了解8086CPU一次读取16位数据也就是一个字。
3.4 mov、add、sub指令
mov指令可以有 (mov 段寄存器,寄存器 ) 那么也有(mov 寄存器,段寄存器 )
有(mov 内存单元,寄存器)那么有(mov 内存单元,段寄存器)
还应该有(mov 段寄存器,内存单元)
(add ds,ax)不能进行操作
3.5 数据段
我们可以将一组长度为N(N<=64KB)、地址连续、起始地址为16的倍数的内存单元当作专门的存储数据的内存空间,从而定义了一个数据段。
检测点3.1:
(1)我在自己win10虚拟环境下内存不一样,就用截图了。
(2)1.指令序列:mov ax,6622
jmp 0ff0:0100
mov ds,ax
mov ax,[0008]
mov ax,[0002]
2.
3. 数据和程序没区别,用寄存器指针位置确定哪里是数据哪里是程序。
3.6 栈
栈就是一个后进先出(LIFO)的地址段,两个基本操作,入栈、出栈。
3.7 CPU提供的栈机制
现在的cpu都有栈机制,8086cpu提供入栈出栈指令,PUSH和POP。出栈入栈都是以字为单位进行的。8086CPU的SS段寄存器和SP寄存器提供栈访问指针。任意时刻,SS:SP指向栈顶元素。
push ax的执行:1.SP = SP-1 2.将ax内容送入SS:SP指向的内存单元中。 入栈时高地址向低地址方向增长。
问题3.6:当10000H~1000FH为空时,sp为10010H指向栈低元素的下面单元。
POP操作与PUSH相反。
3.8 栈顶超界的问题
假设10010H~1001FH当作栈空间,栈空时sp= 0020H,栈满时sp=0010H,如果栈满时再push数据,则栈顶超出栈空间sp=000EF。如果栈为空时再pop数据时,栈顶也会超出栈空间sp=0022H。这样就会覆盖外面的数据造成损失。
8086CPU没有操作对这样的情况做出反应,所以编程时要注意栈空间超界问题。
3.9 push、pop指令
pop指令格式:pop 寄存器或pop 段寄存器
push指令格式:push 寄存器或push 段寄存器
问题3.7:将ax,bx,ds中的数据入栈:10000H~1000FH
问题3.8:入栈ax,bx。出栈bx,ax
问题3.9:利用栈交换ax,bx 将问题3.8中的pop指令交换顺序即可:
问题3.10:不适用mov 内存单元,寄存器 将2266写入10000H中
实质上pop,push就是一种内存传送指令,用mov则只需一步。
3.10 栈段
和段一样的定义:长度N<=64KB地址连续,起始地址为16的倍数的内存单元。
问题3.11:把 10000H~1FFFFH当作栈段使用时,栈为空时,sp=?
为 FFFF+1=10000,但是sp只能存16位所以sp=0000.
问题3.12:一个栈段最大为:根据sp寄存器的大小0~FFFF,所以最大为2的16次方=64KB。
检测点3.2:
1.补全的代码:mov ax,2000
mov ss,ax
mov sp,10
2.: mov ax,1000
mov ss,ax
mov sp,0
实验2 用机器指令和汇编指令编程
1.中提出了新概念:中断机制,在执行mov ss,ax后mov sp,10一起被执行t命令显示不出此条命令。
2. 直接写入代码观察即可:
3. 栈空间内容变化。