我是靠谱客的博主 单纯楼房,最近开发中收集的这篇文章主要介绍【汇编语言04】第3章 寄存器(内存访问)0 前言1 数据段寄存器2 栈段寄存器3 汇编指令push与pop4 小结参考文献,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

  • 0 前言
  • 1 数据段寄存器
    • 1.1 内存中字的存储
    • 1.2 字的传送
    • 1.3 DS和[address]
    • 1.4 数据段
  • 2 栈段寄存器
    • 2.1 栈的简介
    • 2.2 CPU的栈机制
    • 2.3 SS和SP
    • 2.4 栈顶越界问题
  • 3 汇编指令push与pop
    • 3.1 编程要求
    • 3.2 代码示例
  • 4 小结
  • 参考文献

0 前言

  1. 【汇编语言02】第2章 寄存器
  2. 【汇编语言03】实验1:查看CPU和内存,用机器指令和汇编指令编程
  3. 在第2章的学习中,我们主要从CPU如何执行指令的角度讲解了8086CPU的逻辑结构、形成物理地址的方法、与寄存器相关的一些指令、debug工具的使用等。
  4. 在第3章中,我们将从访问内存的角度继续学习几个寄存器。

1 数据段寄存器

1.1 内存中字的存储

  1. 在CPU中,用16位的寄存器来存储一个字,高8位存放高位字节,低8位存放地位字节。
  2. 在内存中存储时,每一个内存单元存储一个字节,连续两个单元存储一个字,与CPU类似地,高地址内存单元存放字型数据的高位字节,低地址内存单元中存储字型数据的低位字节。
  3. 任何两个地址连续的内存单元,N号单元和 N+1号单元,可以将它们看成两个内存单元 ,也可以看成一个地址为N的字单元中的高位字节单元和低位字节单元。

1.2 字的传送

  1. CPU寄存器和内存之间完成数据的传送:使用mov指令。
  2. 因为8086CPU是16位结构的,有16根数据线,所以,一次可以传输16位数据,也就是一个字。那么只要在mov指令中给出16位寄存器,就可以进行16位数据的传送了。

1.3 DS和[address]

  1. 数据段寄存器:DS,偏移地址:[address]。
  2. 代码段寄存器:CS,偏移地址:IP。
  3. 要实现:将内存地址为10002H的内容写入到寄存器AX中。需要以下步骤:
    (1)要先使用以下命令将数据段地址DS修改为1000H:
    mov ax,1000H
    mov ds,ax
    不能直接将1000H直接写入ds,如下,因为寄存器不支持这种指令。
    mov ds,1000H
    (2)将内容赋值给寄存器ax,此处表示在数据段地址的基础上偏移2个地址,即10002H。
    mov ax,[2]

1.4 数据段

  1. 与代码段概念类似,我们可以将一组长度为N、地址连续、其实地址为16的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段。
  2. 与代码段概念类似,将一段内存当作数据段,是我们在编程时的一种安排,可以在具体操作的时候,用ds存放数据段的段地址,再根据需要,用相关指令访问数据段中的具体单元。

2 栈段寄存器

2.1 栈的简介

  1. 从访问方式理解栈:栈是一种具有特殊的访问方式的存储空间。
  2. 特殊性:栈的特殊性在于,最后进入这个空间的数据,最先出去。
  3. 栈段:我们可以将长度位N的一组地址连续、起始地址为16的倍数的内存单元当作栈空间来使用,从而定义了一个栈段。将一段内存当作栈段,仅仅是我们在编程时的一种安排。CPU并不会由于这种安排,就在执行push和pop等栈操作指令时自动地将我们定义的栈段当作栈空间来访问。

2.2 CPU的栈机制

  1. 现在CPU都有栈的设计,提供相关指令来以栈的方式访问内存空间。这意味着基于CPU编程的时候,可以将一段内存当作栈来使用。
  2. PUSH 入栈指令:比如 push ax 表示将寄存器ax中的数据送入栈中。
  3. POP 出栈指令:比如 pop ax 表示将栈顶取出数据送入ax中。
  4. 8086CPU的入栈出栈操作都是以字为单位进行的。下面是CPU栈方式方式的简要过程。
    在这里插入图片描述

2.3 SS和SP

  1. 为了给CPU描述栈顶的位置,需要相应的寄存器来表示,这里用到了段寄存器SS寄存器SP
  2. 任意时刻,SS:SP指向栈顶元素,push指令和pop指令执行时,CPU从SS和SP中得到栈顶的地址。
  3. push ax 指令执行原理,由两步完成:
    (1)SP = SP - 2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶。
    (2)将ax中的内容送入SS:SP指向的内存单元处,SS:SP指向当前栈顶前面的单元。
    在这里插入图片描述
  4. pop ax 指令执行原理,由两步完成:
    (1)将SS:SP指向的内存单元处的数据送入ax中;
    (2)SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
    在这里插入图片描述

2.4 栈顶越界问题

  1. 问题描述:CPU中用SS和SP指示栈顶的地址,但是SS和SP只是记录了栈顶的地址,仅依靠SS和SP可以保证在入栈和出栈是找到栈顶,但是,无法保证在入栈和出栈时栈顶位置不超出栈空间。
  2. push指令越界问题:如下图描述了多次执行push指令后,栈空间已满,再次执行时SS:SP指向1000EH,栈顶超出了栈空间,ax中的数据送入到1000EH单元处,将栈空间外的数据覆盖。
    在这里插入图片描述
  3. pop指令越界问题:当多次执行pop指令后,栈空,SS:SP指向10020H;再次执行pop指令时,SS:SP指向10022H,栈顶超出了栈空间。此后如果再次执行push指令,10020H和10021H中的数据将被覆盖。
    在这里插入图片描述
  4. 越界问题的危害:当栈慢的时候再次执行push指令入栈、或栈空的时候再使用pop指令出栈,都将发生栈顶越界问题。越界问题时有可能将其他程序的代码或数据意外改写,将会引发一连串的错误。
  5. 越界问题的解决:如果CPU中有记录栈顶上限和栈底的寄存器,这样就能通过填写这些寄存器来指定栈空间的范围,然后CPU在执行push指令时靠检测栈顶上限寄存器、在执行pop指令的时候开检测栈底寄存器保证不会越界。不过,8086CPU实际上并没有这些寄存器,只能在编程的时候根据需要预留大空间的栈。

3 汇编指令push与pop

3.1 编程要求

  1. 将10000H~1000FH 这段空间当作栈,初始状态是空的;
  2. 设置AX=001AH,BX=001BH;
  3. 将AX、BX中的数据入栈;
  4. 然后将AX、BX清零;
  5. 从栈中恢复AX、BX原来的内容。

3.2 代码示例

mov ax,1000H
mov ss,ax		# 不能直接将值赋给ss
mov sp,0010H	# 设置栈偏移地址
mov ax,001AH
mov bx,001BH
push ax			# 将ax放入栈
push bx			# 将bx放入栈
sub ax,ax		# 清空ax
sub bx,bx		# 清空bx
pop bx			# 因为bx在上面,所以需要先pop bx
pop ax

在这里插入图片描述

4 小结

  1. 我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。这完全是我们自己的安排。
    (1)我们可以用一个段存放数据,将它定义为“数据段”。对于数据段,将它的段地址放在 DS中,用mov、add、sub等访问内存单元的指令时,CPU就将我们定义的数据段中的内容当作数据段来访问。
    (2)我们可以用一个段存放代码,将它定义为“代码段”。对于代码段,将它的段地址放在 CS中,将段中第一条指令的偏移地址放在IP中,这样CPU就将执行我们定义的代码段中的指令。
    (3)我们可以用一个段当作栈,将它定义为“栈段”。对于栈段,将它的段地址放在SS中,将栈顶单元的偏移地置放在 SP 中,这样CPU在需要进行栈操作的时候,比如执行 push、pop 指令等,就将我们定义的栈段当作栈空间来用。
  2. 8086CPU提供了栈操作机制,方案如下:
    (1)在SS,SP中存放栈顶的段地址和偏移地址;
    (2)提供入栈和出栈指令,他们根据SS:SP指示的地址,按照栈的方式访问内存单元。
  3. push指令的执行步骤:
    (1)SP=SP-2;
    (2)向SS:SP指向的字单元中送入数据。
  4. pop指令的执行步骤:
    (1)从SS:SP指向的字单元中读取数据;
    (2)SP=SP-2。

参考文献

  1. 《一文读懂堆与栈的区别》
  2. 《寄存器(内存访问)01》小甲鱼零基础视频课程
  3. 《寄存器(内存访问)02》小甲鱼零基础视频课程
  4. 《寄存器(内存访问)03》小甲鱼零基础视频课程
  5. 《寄存器(内存访问)04》小甲鱼零基础视频课程
  6. 《寄存器(内存访问)05》小甲鱼零基础视频课程
  7. 《寄存器(内存访问)06》小甲鱼零基础视频课程
  8. 《寄存器(内存访问)07》小甲鱼零基础视频课程

最后

以上就是单纯楼房为你收集整理的【汇编语言04】第3章 寄存器(内存访问)0 前言1 数据段寄存器2 栈段寄存器3 汇编指令push与pop4 小结参考文献的全部内容,希望文章能够帮你解决【汇编语言04】第3章 寄存器(内存访问)0 前言1 数据段寄存器2 栈段寄存器3 汇编指令push与pop4 小结参考文献所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部