汇编语言学习笔记 -第三章

本章详细介绍了8086CPU中的寄存器如何存储和访问内存,特别是内存中字的存储方式、DS与地址的关系、字的传送、以及push和pop指令在栈操作中的应用。通过实例解析了段地址、偏移地址、数据段、栈段的概念,并探讨了栈顶超界问题及其危害。
摘要由CSDN通过智能技术生成

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

3.1 内存中字的存储

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

举例:用 0,1 两个内存单元存放数据 2000(4E20H), 用 2,3 两个内存单元存放数据 18(0012H)。
在这里插入图片描述

  • 字单元:即存放一个字型数据(16 位)的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。
  • 将起始地址为 N 的字单元简称为 N 地址单元。

举例:比如一个字单元由 2,3 两个内存单元组成,则这个字单元的起始地址为 2,我们可以说这是 2 地址。

对于图3.1:
(1) 0地址单元中存放的字节型数据是多少?
(2) 0地址字单元中存放的字型数据是多少?
(3) 2地址单元中存放的字节型数据是多少?
(4) 2地址字单元中存放的字型数据是多少?
(5) 1地址字单元中存放的字型数据是多少?
思考后看分析。
分析:
(1) 0地址单元中存放的字节型数据:20H;
(2) 0地址字单元中存放的字型数据: 4E20H;
(3) 2地址单元中存放的字节型数据:12H;
(4) 2地址字单元中存放的字型数据:0012H;
(5) 1地址字单元,即起始地址为1的字单元,它由1号单元和2号单元组成,用这 两个单元存储一个字型数据,高位放在2号单元中,即:12H,低位放在1号单元中,即:4EH,它们组成字型数据是124EH,大小为:4686。

  • 任何两个地址连续的内存单元,N号单元和N+1号单元,可以将它们看成两个内存单元,也可看成一个地址为N的字单元中的高位字节单元和低位字节单元。

3.2 DS 和 [address]

  • CPU 要先给出一个内存单元的地址,才能读写这个内存单元。
  • 在 8086PC 中,内存地址由段地址和偏移地址组成。8086CPU 中 DS 寄存器通常用来存放要访问数据的段地址。

举例:比如我们要读取 10000H 单元的内容,可以执行如下程序段:

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

上面的3条指令将10000H(1000:0)中的数据读到al中。

  • mov 指令传送:
    • 将数据直接送入寄存器
    • 将一个寄存器中的内容送到另一个寄存器中
    • 将一个内存单元中的内容送到一个寄存器中
  • “[···]” 表示一个内存单元, “[···]” 中的 0 表示偏移地址。指令执行时,8086CPU 自动取 ds 中的数据为内存单元的段地址。
  • 8086CPU 不支持将数据直接送入段寄存器的操作,需要用一个寄存器中转。

举例:写几条指令,将 al 中的数据送入内存单元 10000H 中。

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

3.3 字的传送

  • 8086CPU 是 16 位结构,有 16 根数据线,所以,可以一次性传送 16 位数据,即一个字。

举例:

mov bx,1000H
mov ds,bx
mov ax,[0]    ;1000:0 处的字型数据送入 ax
mov [0],cx    ;cx 中的 16 位数据送到 1000:0 处

举例:
在这里插入图片描述
在这里插入图片描述

举例:
在这里插入图片描述
在这里插入图片描述

3.4 mov、add、sub 指令

  • mov 指令有以下几种形式:
形式例子
mov 寄存器,数据比如:mov ax,8
mov 寄存器,寄存器比如:mov ax,bx
mov 寄存器,内存单元比如:mov ax,[0]
mov 内存单元,寄存器比如:mov [0],ax
mov 段寄存器,寄存器比如:mov ds,ax
mov 寄存器,段寄存器比如:mov ax,ds
mov 段寄存器,内存单元
  • add 和 sub 指令同 mov 一样,都有两个操作对象,有以下几种形式:
形式例子
add寄存器,数据比如:addax,8
add寄存器,寄存器比如:addax,bx
add寄存器,内存单元比如:addax,[0]
add内存单元,寄存器比如:add[0],ax
sub寄存器,数据比如:sub ax,9
sub寄存器,寄存器比如:subax,bx
sub寄存器,内存单元比如:subax,[0]
sub内存单元,寄存器比如:sub[0],ax

3.5 数据段

  • 对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。将一组长度为N(N <= 64KB)、地址连续、起始地址为16的倍数
    的内存单元当作专门存储数据的内存空间,从而定义了一个数据段.

举例:比如用123B0H〜123B9H这段内存空间来存放数据,我们就可以认为,123B0H〜123B9H这段内存是一个数据段,它的段地址为 123BH,长度为 10 个字节。

举例:在这里插入图片描述

举例:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.6 栈

  • 栈是一种具有特殊的访问方式的存储空间。它的特殊性就在于,最后进入这个空间的数据,最先出去。

举例:盒子代表栈,书代表数据
在这里插入图片描述
在这里插入图片描述

  • 栈有两个基本的操作:入栈和出栈。
  • 入栈就是将一个新的元素放到栈顶,出栈就是从栈顶取出一个元素。栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。
  • 栈的这种操作规则被称为:LIFO(Last In FirstOut,后进先出)。

3.7 CPU 提供的栈机制

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

比如,push ax表示将寄存器ax中的数据送入栈中,pop ax表示从栈顶取出数据送入ax.8086CPU的入栈和出栈操作都是以字为单位进行的。

举例:将 10000H~1000FH 这段内存当作栈来使用。
在这里插入图片描述

  • 8086CPU中,CS、IP中存放着当前指令的段地址和偏移地址。段寄存器SS和寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。
  • 任意时刻,SS:SP 指向栈顶元素.push指令和pop指令执行时,CPU从SS和SP中得到栈顶的地址。

举例:
在这里插入图片描述
从图中我们可以看出,8086CPU中,入栈时,栈顶从高地址向低地址方向増长。

举例:栈空的状态
在这里插入图片描述

举例:pop 指令的执行过程
在这里插入图片描述
原数据依然存在,不属于栈,新数据重新入栈时覆盖旧数据。

3.8 栈顶超界的问题

举例:执行 push 后栈顶超出栈空间
在这里插入图片描述

举例:执行 pop 后栈顶超出栈空间
在这里插入图片描述

  • 栈顶越界非常危险,有可能改写栈外空间的数据,引发一系列意外错误。
  • 8086CPU 没有检查栈顶越界的寄存器,它只考虑当前的栈顶在何处,当前要执行的指令是哪条。

3.9 push、pop 指令

  • push、pop 指令形式:
push寄存器 ;将一个寄存器中的数据入栈
pop寄存器 ;出栈,用一个寄存器接收出栈的数据
push段寄存器	;将一个段寄存器中的数据入栈
pop段寄存器	;出栈,用一个段寄存器接收出栈的数据
push内存单元 ;将一个内存字单元处的字入栈(注意:栈操作都是以字为单位)
pop内存单元 ;出栈,用一个内存字单元接收出栈的数据

比如:
mov ax,1000H
mov ds,ax ;内存单元的段地址要放在ds中
push [0] ;将1000:0处的字压入栈中
pop [2] ;出栈,出栈的数据送入1000:2处

  • 指令执行时,CPU 要知道内存单元的地址,可以在push、pop 指令中只给出内存单元的偏移地址,段地址在指令执行时,CPU 从 ds 中取得。

举例:
在这里插入图片描述

举例:
在这里插入图片描述
在这里插入图片描述

举例:
在这里插入图片描述
在这里插入图片描述

举例:
在这里插入图片描述
在这里插入图片描述

  • push、pop实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与mov指令不同的是,push和pop指令访问的内存单元的地址不是在指令中给出的,而是由SS:SP指出的。同时,push和pop指令还要改变SP中的内容。

  • 我们要十分清楚的是,push和pop指令同mov指令不同,CPU执行mov指令只需一步操作,就是传送,而执行push、pop指令却需要两步操作,执行push时,CPU的两步操作是:先改变SP,后向SS:SP处传送。执行pop时,CPU的两步操作是:先读取SS:SP处的数据,后改变SP。

  • 注意,push, pop等栈操作指令,修改的只是SP。也就是说,栈顶的变化范围最大为:0~FFFFH。

  • 提供:SS、SP指示栈顶;改变SP后写内存的入栈指令;读内存后改变SP的出栈指令。这就是 8086CPU 提供的栈操作机制。

在这里插入图片描述
在这里插入图片描述

3.10 栈 段

  • 对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。
  • 我们可以将长度为N(N <= 64KB)的一组地址连续、起始地址为16的倍数
    的内存单元,当作栈空间来用,从而定义了一个栈段。

比如,我们将10010H-1001FH这段长度为16字节的内存空间当作栈来用,以栈的方式进行访问。这段空间就可以称为一个栈段,段地址为1001H,大小为16字节。

  • 将一段内存当作栈段,仅仅是我们在编程时的一种安排,CPU并不会由于这种安排,就在执行push、pop等栈操作指令时自动地将我们定义的栈段当作栈空间来访问。
  • 将SS:SP指向我们定义的栈段,从而 push、pop 等栈操作指令可以访问我们定义的栈段。

举例:
在这里插入图片描述
SP = 0000H。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值