汇编第三节-寄存器(内存访问)

第三节 :寄存器(内存访问)

1. 内存中字的存储:

16位寄存器来存储一个字。高8位存放高位字节,低8位存放低位字节

字单元:存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。

将起始地址为N的字单元简称为N地址字单元。

2. DS[address]

DS寄存器:通常用来存放要访问数据的段地址。

[address]表示一个偏移地址为address的内存单元。

Eg:读取10000H单元的内容:

Mov bx,1000H

Mov ds,bx

Mov a1,[0]

[]说明操作对象是一个内存单元,段地址默认放在ds中,指令执行时,8086CPU会自动从ds中取出。

注意:mov ds,1000H 指令非法。只能用一个寄存器进行中转。

Eg:将a1中的数据送到内存单元10000H:

Mov bx,1000H

Mov ds,bx

Mov [0],a1

 

3. 字的传送:

Eg:指令执行后寄存器ax    10000H存放2310001H存放11

Mov bx,1000H

Mov ds,bx

Mov a1,[0]       ----->ax=1123H

指令执行时,字型数据的高8位送入ah,低8位送到al。区分字单元

 

4.movaddsub指令:

Mov类似于赋值,add 相加,sub相减

推测:有mov 段寄存器,寄存器 是否有 mov 寄存器,段寄存器

Mov 内存单元,段寄存器?

Mov 段寄存器,内存单元?

Movaddsub具有两个操作对象的指令。Jmp是具有一个操作对象的指令。

 

5. 数据段:

可以将一组长度为NN<=64kb),地址连续,起始地址为16的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段。、

Eg:累加这个数据段中的前3个单元中的数据

Mov ax,123BH

Mov ds,ax

Mov a1,0 a1存放累加结果

Add a1,[0] 将数据段第一个单元(偏移地址为0)中的数值加到a1中;

Add a1,[1]

Add a1,[2]

累加数据段中的前3个字型数据

Mov ax,123BH

Mov ds,ax

Mov ax,0 a1存放累加结果

Add ax,[0] 将数据段第一个单元(偏移地址为0)加到ax中;

Add ax,[2] 将数据段第二个单元(偏移地址为2)加到ax中;

Add ax,[4]

 

6. 栈:LIFOlast in first out,后进后出):

7. CPU提供的栈机制:

8086CPU提供入栈和出栈指令,最基本的两个是PUSH(入栈)和POP(出栈)

出入栈的操作都是以字为单位的。

Eg:栈操作

Mov ax0123H

Push ax

Pop ax

注意:字型数据用两个单元存放,高地址单元存放8位,低地址单元存放低8位。

Cpu如何知道栈顶的位置?

8086CPU中,有两个寄存器,段寄存器SS和寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。

任意时刻,SSSP指向栈顶元素。

PUSH ax的执行,由以下两步完成。//POP ax相反

1. SP=SP-2SSSP指向当前栈顶前面单元,以当前栈顶前面的单元为新的栈顶;

2. ax中的内容送入SSSP指向的内存单元处,SSSP此时指向新栈顶。

 

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

**:如果将10000H~1000FH这段空间当作栈,初始状态栈是空的,此时SS=1000HSP=

SP应该等于0010H

栈空时SSSP指向栈空间最高地址单元的下一个单元,每次执行,SP-=2。栈中没有元素,也就不存在栈顶元素,所以SSSP只能指向栈的最底部单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址+2.

Eg:栈最底部字单元的地址为1000:000E,所以栈空时,SP=0010H

 

8. 栈顶超界的问题:

如何保证在入栈,出栈时,栈顶不会超出栈空间?

8086CPU中并没有寄存器来检测栈顶上下限,但是栈顶超界很危险。

8086工作的机理,只考虑当前的状况,只考虑当前的情况:当前栈顶在何处,当前要执行的指令是哪一条。

在编程的过程自己操心栈顶超界问题:要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;执行出栈操作的时候,防止栈空的时候继续出栈而导致的超界

 

 

9.PUSHPOP指令:

栈空间是内存空间的一部分,只是一段可以以一种特殊的方式进行访问的内存空间。

PUSH/POP 寄存器  将一个寄存器中的数据入栈/出栈,用一个寄存器接收出栈的数据

PUSH/POP 段寄存器 同上;

PUSH  内存单元 将一个内存字单元处的字入栈(注意:栈操作都是以字为单位)

POP   内存单元 出栈,用一个内存字单元接收出栈的数据

Eg:将10000H~1000FH这段空间当作栈,初始状态栈是空的,将AXBXDS数据入栈

Mov ax1000H

Mov ssax      //设置栈的段地址,ss=1000H,不能直接向段寄存器SS送入数据

Mov sp0010H  //设置栈顶的偏移地址,因栈为空,所以SP=0010H

Push ax

Push bx

Push ds

 

清空AXBX

Sub axax 2个字节)

Sub bxbx

ax清零,也可以用mov ax03个字节)

 

交换AXBX中的数据

Push ax  push bx pop ax pop bx

 

执行push时,CPU的两步操作:先改变SP,后向SSSP处传送

执行POP时,CPU的两步操作:先读取SSSP处的数据,后改变SP

 

10. 栈段:

可以根据需要,将一组内存单元定义为一个段。将长度为NN<=64KB)的一组地址连续,起始地址为16的倍数的内存单元,当作栈空间来用,定义一个栈段。

 

可以用一个段存放数据,将定义为“数据段”

---->段地址放在DS中,用MOVADDSUB等访问内存单元的指令。

 

可以用一个段存放代码,将定义为“代码段”

---->段地址放在CS中,将段中第一条指令的偏移地址放在IP中。

 

可以用一个段当作栈,将定义为“栈段”

---->段地址放在SS中,将栈顶单元的偏移地址放在SP中,执行POPPUSH将栈段当做栈空间来用。

 


DebugT命令在执行修改寄存器ss的指令时,下一条指令也紧接着被执行。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值