在第五章的学习之后, 因为实验课在老师的抽查之后发现前面的知识很多都忘了, 便对之前的知识进行了一遍系统的复习, 对汇编的基础知识基本都已经掌握, 也有了更加深刻的认识.
在第三章中我们主要从内存访问的角度来继续学习 CPU 执行指令的原理, 并进一步的学习上一章的寄存器.
<1 > 内存中字的存储
字由高位字节和低位字节组成, 用 16 位寄存器来存储. 高八位存放高位字节, 低八位存放低位字节. 字需要两个地址连续的内存单元 (一个字节) 来存储, 字的低位字节存放在低地址单元中, 高位字节存放在高地址单元中. 如下图, 我们想要存放数据 20000(4E20H)在 0,1 两个内存单元中, 0 号单元为低地址空间, 1 号单元为高地址单元, 所以 1 号单元中存放高位字节 4EH,0 号单元中存放低位字节 20H.(小尾顺序)
字单元: 存放一个字型数据的内存单元, 由两个地址连续的内存单元组成. 高地址内存单元中存放字型数据的高位字节, 低地址内存单元中存放字型数据的低位字节. 我们可以将起始地址为 N 的字单元简称为 N 地址字单元.
<2>DS 和[address]
CPU 如果要想读写一个内存单元, 必须有这个内存单元的地址. 在 8086PC 中, 内存地址是由段地址和偏移地址共同组成的. DS 寄存器就是通常用来存放所要访问数据的段地址的. 比如我们想要读取 10000H 内存单元的内容, 可以使用如下的程序段去实现:(1)mov bx,1000H(2)mov ds,bx(3)mov al,[0] 第一条语句是吧所要访问的内存单元的段地址暂存在寄存器 bx 中, 第二条语句是把寄存器 bx 中所存的 1000H 存入段寄存器 ds 中. 之前我们使用 "mov ax,1" 语句来实现把数据送入寄存器, 而 8086CPU 不支持将数据直接送入段寄存器的操作, 所以我们使用一个寄存求进行中转从而完成将数据送入段寄存器. 第三条语句是把以段寄存器 DS 中的数据为段地址, 以 [ ] 中的数据为偏移地址, 访问这一内存空间的数据, 并将其送入寄存器 al 中.
PS:mov [0],al 语句可以实现把 al 中的数据送入内存单元 ds:0 中.
<3>mov,add,sub 指令
mov 指令可以有如下的几种形式:
mov 寄存器, 数据
mov 寄存器, 寄存器
mov 寄存器, 内存单元
mov 内存单元, 寄存器
mov 段寄存器, 寄存器
mov 寄存器, 段寄存器
mov 内存单元, 段寄存器
mov 段寄存器, 内存单元
add 和 sub 指令也有两个操作对象, 可以有如下的几种形式:
add 寄存器, 数据
add 寄存器, 寄存器
add 寄存器, 内存单元
add 内存单元, 寄存器
sub 寄存器, 数据
sub 寄存器, 寄存器
sub 寄存器, 内存单元
sub 内存单元, 寄存器
经过自行验证发现 add 和 sub 是无法对段寄存器进行操作的.
<4 > 栈
栈是一种有特殊访问方式的存储空间, 先进后出(LIFO).
8086CPU 提供入栈和出栈的指令, 最基本的两个为 PUSH 和 POP.push ax 表示把寄存器 ax 中的数据送入栈中, pop ax 表示从栈顶取出数据送入 ax. 在入栈和出栈的操作中都是以字为单位进行的. 栈底: 固定的一端, 栈区最高地址单元的前一个单元. 下图即为一个栈空间, 我们对其进行相关的操作.
在上图中, 我们想要把 1126H 存入栈区, 首先先把栈顶上移两个单元, 即栈顶 - 2 = 栈顶, 然后存入数据.
从栈区取出元素 5020H 首先取出数据, 然后栈顶下移两个单元, 栈顶 + 2 = 栈顶.
8086CPU 中有两个寄存器, 段寄存器 SS 和寄存器 SP, 栈顶的段地址存放在 SS 中, 偏移地址存放在 SP 中, 任意时刻 SS:SP 都指向栈顶元素. 对应上面的 push 和 pop 操作, 入栈时,(1)SP=SP-2,SS:SP 指向当前栈顶前面的单元, 并以此为新的栈顶.(2)将 ax 中的内容送入 SS:SP 指向的内存单元处, SS:SP 此时指向新的栈顶. 出栈时,(1)将 SS:SP 指向的内存单元处的数据送入 ax 中.(2)SP=SP+2,SS:SP 指向当前栈顶下面的单元, 并以此为新的栈顶.
当栈满时用 push 入栈和栈空时用 pop 出栈都会发生栈顶超界问题, 会对栈以外的数据进行改写, 可能引发一连串的错误. 而 8086CPU 也没有一定的机制去防止此类现象的发生, 所以我们在使用栈的时候进行入栈和出栈操作要先确定栈并没有处于满或者空的状态.
pop 和 push 指令可以在寄存器和内存单元, 段寄存器和内存单元, 内存单元和内存单元之间传送数据.
当我们将长度为 N 的一组连续并且起始地址为 16 的倍数的内存单元当作栈空间使用时, CPU 并不知道这是栈段, 我们只要使 SS:SP 指向我们所定义的栈段即可.
小结: 在这章我们学习了内存访问的相关指令及其规则和栈的结构与指令, 学习了新的段寄存器 SS:SP. 栈在解决某些问题时由于先进后出的特点具有一定的优势, 比如逆序输出等, 主要还是要在脑子中对其结构有很好的刻画才能很好的掌握它的运行机制.
第三章 寄存器(内存访问)
来源: http://www.bubuko.com/infodetail-2867279.html