从0学习汇编语言(3)寄存器(内存访问)

716 阅读4分钟

《从0学习汇编语言目录》

第三章 寄存器(内存访问)

3.1 内存中字的存储

CPU中,用16位寄存器来存储一个字,高8位放高位字节,低8位放低位字节,如下图所示,2个内存单元存放一个数据,4E20由下图表示,20放在低位,4E放在高位。

3.2 DS和[adress]

8086中的DS寄存器,通常用来存放要访问数据的段地址,例如下面指令

mov bx, 1000
mov ds,bx
mov al, [0]

上面代码表示读取ds:0 也就是1000:0地址中的数据读取到al中。

3.3 字的传送

mov bx, 1000
mov ds,bx
mov al, [0]
mov [0], cx

下面代码表示将cx中的16位数据传送到1000:0出 (更改内存中的数据)

3.2和3.3主要讲述了如何读取地址中的数据,以及如何像内存中赋值。[adress]是取地址中的值,或者是往地址里赋值。

3.4 mov、add、sub指令

mov

mov 寄存器,数据  mov ax,8
mov 寄存器,寄存器 mov ax,bx
mov 寄存器,内存单元 mov ax,[0]
mov 内存单元,寄存器 mov [0],ax
mov 段寄存器,寄存器 mv ds, ax

add or sub

add 和 sub 操作形式一致

add 寄存器,数据  add ax,0
add 寄存器,寄存器 add ax, bx
add 寄存器,内存单元 add ax,[0]
add 内存单元,寄存器 add [0],ax

3.5 数据段

在内存中,存储数据的我们会定义一个段,叫数据段,如何从数据段中读取信息呢,我们会用到ds[adress]

mov ax,123B
mov ds,ax
mov al,0
mov al,[0]  
mov al,[2]
mov al,[4]

将123B:0,123B:2,123B:3的内存中的数据,逐次赋值到al中。思考下为什么要是0,2,4呢。 因为使用[adress]取值或者赋值是16位的,是一个,所以每次间隔2个。如3.1所讲

3.6 栈

栈是一种数据结构,分为push(入栈)和pop(出栈)操作,以先进后出的形式操作数据,如下图所示

3.7 CPU提供的栈机制

现金的CPU都有栈的设计,8086CPU也不例外,8086CPU提供相关的指令来以栈的形式访问内存空间,两个基本操作为push(入栈)、pop(出栈)比如: push ax表示将寄存器ax的数据送入栈中。 pop ax表示从站定取出来数据送入ax中。 8086中出栈入栈都是以为单位的。

CPU要知道当前指令的所在位置,就要记录栈底地址和偏移量,8086CPU有两个寄存器,分别为SS寄存器和SP寄存器。在任何时刻SS:SP指向栈顶元素。 push和pop执行在执行时,CPU从SS和SP中得到栈顶地址。

push ax的执行由以下两步完成。 1)SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新栈顶(为什么是-2因为CPU操作都是以为单位) 2)将ax的内容送到SS:SP指令指向的内存单元处,此时SS:SP指向新的栈顶(参考3.1字的存储

入栈时,栈顶从高地址向低地址方向增长

3.8 栈顶超界的问题

当我们进行pop和push的时候,会有一种临界值。 就是当pop空栈的时候,sp依然会+2, push满栈的时候,sp依然会-2。这样赋值会造成栈空间意外的内存被改动,这就是我们说的栈顶超界的问题。在8086CPU中需要自己控制。

push、pop指令

push和pop指令格式如下形式

push 寄存器  ;将一个寄存器中的数据入栈
pop 寄存器   ;用一个寄存器接收出栈的数据
也可以
push 段寄存器
pop 段寄存器

push 内存单元
pop 内存单元

push和pop本质上是一种内存传送指令。

3.10 栈段

我们将内存空间当栈使用,以栈的方式进行访问,这段空间就可以成为栈段 如果我们将10000-1FFFFF这段空间当做栈段,初始状态栈是空的,SS=1000,SP=? 分析: 栈最底部的字单元地址为1000:FFFE,所以当第一个元素pop的时候,SP= FFFE + 2 = 10000, SP为16位,所以SP=0;

在从另一个角度去操作。当栈快满的时候,SP也为0(1000:2时ps = ps - 2),这样,如果再次亚展,栈顶将环绕,覆盖原来的内容,所以一个栈的最大内容为64KB

从0学习汇编语言(4)第一个程序