寄存器(内存访问)

从访问内存的角度继续学习几个寄存器<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

首先理解几个要点:

1.内存中字的存储

n        在0地址处开始存放20000:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />

n        0号单元是低地址单元,1号单元是高地址单元。

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

2. DS[address]

n        CPU要读取一个内存单元的时候,必须先给出这个内存单元的地址;

n        在8086PC中,内存地址由段地址和偏移地址组成。

n        8086CPU中有一个 DS寄存器,通常用来存放要访问的数据的段地址。

n           例如:我们要读取10000H单元的内容可以用如下程序段进行:

mov bx,1000H

mov ds,bx

mov al,[0]

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

mov指令的格式:

mov 寄存器名,内存单元地址

“[…]”表示一个内存单元, “[…]”中的0表示内存单元的偏移地址。

那么内存单元的段地址是多少呢?就是上面的ds

备注:8086CPU不支持将数据直接送入段寄存器的操作,ds是一个段寄存器。

(硬件设计的问题)

mov ds,1000H 是非法的。

数据-一般的寄存器-段寄存器

明白了以上原理,我们具体来看看字的传送

3.字的传送

因为8086CPU是16位结构,有16根数据线,所以,可以一次性传送16位的数据,也就是一次性传送一个字。

看下面的图清晰的描述了这个过程:

内存中的情况如右图,写出下面指令执行后寄存器ax,bx,cx中的值。

分析后就可以知道

Ax=1000h

Ds=1000h

Ax=1123h

Bx=6622h

Cx=2211h

Bx=6622h+2211h=8833hh

Cx=8833hh

现在您可以练习一下,看图写出每行运行后寄存器的结果,如下:

参考答案提供上来:

通过上面的分析,实际上我们已经接触到了以下几种指令:

mov 寄存器,数据

 mov 寄存器,寄存器

 mov 寄存器,内存单元

 mov 内存单元,寄存器

 mov 段寄存器,寄存器

mov 内存单元,段寄存器

mov 段寄存器,内存单元

add和sub指令同mov一样,都有两个操作对象。

4. 数据段

前面讲过,对于8086PC机,我们可以根据需要将一组内存单元定义为一个段。

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

比如我们用123B0H~123B9H这段空间来存放数据:

段地址:123BH

长度:10字节

如何访问数据段中的数据呢?

将一段内存当作数据段,是我们在编程时的一种安排,我们可以在具体操作的时候 ,用 ds 存放数据段的段地址,再根据需要,用相关指令访问数据段中的具体单元。

例子:

我们将123B0H~123BAH的内存单元定义为数据段,我们现在要累加这个数据段中的前3个单元中的数据,代码如下:

5.栈的操作(先进后出)

push 指令的执行过程

先来看入栈的操作,用图来分析:

解释如下:

n        我们将10000H~1000FH 这段空间当作栈段,SS=1000H,栈空间大小为16 字节 ,栈最底部的字单元地址为1000:000E。

      任意时刻,SS:SP指向栈顶,当栈中只有一个元素的时候,SS = 1000H,SP=000EH。 

n        栈为空,就相当于栈中唯一的元素出栈,出栈后,SP=SP+2 ,SP 原来为 000EH,加 2 后SP=10H,所以,当栈为空的时候,SS=1000H,SP=10H。

再来看看出栈的操作:

解释如下:

n        出栈后,SS:SP指向新的栈顶 1000EH,pop操作前的栈顶元素,1000CH 处的2266H 依然存在 ,但是,它已不在栈中。

n        当再次执行push等入栈指令后,SS:SP移至1000CH,并在里面写入新的数据,它将被覆盖。

SS和SP只记录了栈顶的地址,依靠SS和SP可以保证在入栈和出栈时找到栈顶。

可是,如何能够保证在入栈、出栈时,栈顶不会超出栈空间。

栈顶超界的问题

看下面的图:

下面来解释一下:

n        8086CPU不保证对栈的操作不会超界。

这就是说, 8086CPU 只知道栈顶在何处(由SS:SP指示),而不知道读者安排的栈空间有多大。这点就好像 ,CPU 只知道当前要执行的指令在何处(由CS:SP指示)而不知道读者要执行的指令有多少。

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

看下面栈顶超出栈空间的情况:

 

解释如下:

  1/当栈空时,此时ss=1000h,sp=0020h;

当执行了八次压栈后,栈满了,此时ss=1000h,sp=0010h;

如果再执行一次,那么此时ss=1000h,sp=sp-2=000e,这样就把其它内存地址给复盖了,这对程序来讲是致命 的。

 

出栈的原理和入栈原理类似,在此就不用图描述了。读者可自己去体会。

总结如下:

n

n        我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。这完全是我们自己的安排。

n        我们可以用一个段存放数据,将它定义为“数据段”;

n        我们可以用一个段存放代码,将它定义为“代码段”;

n        我们可以用一个段当作栈,将它定义为“栈段”;

n        我们可以这样安排,但若要让CPU按照我们的安排来访问这些段,就要:

n        对于数据段,将它的段地址放在 DS中,用mov、add、sub等访问内存单元的指令时,CPU就将我们定义的数据段中的内容当作数据段来访问;

n        对于代码段,将它的段地址放在 CS中,将段中第一条指令的偏移地址放在IP中,这样CPU就将执行我们定义的代码段中的指令;

n        对于栈段,将它的段地址放在SS中,将栈顶单元的偏移地置放在 SP 中,这样CPU在需要进行栈操作的时候,比如执行 push、pop 指令等,就将我们定义的栈段当作栈空间来用

可见,不管我们如何安排 ,CPU 将内存中的某段内存当作代码 ,是因为CS:IP指向了那里;CPU将某段内存当作栈 ,是因为 SS:IP 指向了那里。

转载于:https://www.cnblogs.com/mfm11111/archive/2009/03/26/1422648.html

一步步学习汇编系列(7)相关推荐

  1. 一步步学习汇编(8)之指令

    要理解ret,retf,call指令,必须要先理清以下汇编基础知识: 一.             [bx]和内存单元<?xml:namespace prefix = o ns = " ...

  2. 【转】学习汇编前你应该知道的知识

    转载地址:http://www.zxbc.cn/html/20070611/22772.html 1.汇编需要什么工具和程序,到哪里下载?     目前阶段,汇编程序仅需要两个程序就够了.masm.e ...

  3. 从0开始学习GitHub系列之「Git 速成」

    从0开始学习GitHub系列之「Git 速成」 糖果果| 2016-06-24 10:55    浏览量(32)    评论(0)   推荐(0) 数据 小编注:[从0开始学习 GitHub]是一个系 ...

  4. 从0开始学习GitHub系列之「认识并加入GitHub」

    从0开始学习GitHub系列之「认识并加入GitHub」 糖果果| 2016-06-16 16:01    浏览量(245)    评论(0)   推荐(0) 数据 小编注:[从0开始学习 GitHu ...

  5. 从0开始学习 GitHub 系列之「初识 GitHub」

    ## 1. 写在前面 我一直认为 GitHub 是程序员必备技能,程序员应该没有不知道 GitHub 的才对,没想到这两天留言里给我留言最多的就是想让我写关于 GitHub 的教程,说看了不少资料还是 ...

  6. 基于asp.net + easyui框架,一步步学习easyui-datagrid——界面(一)

    从这篇博客,我会一步步的为大家讲解,easyui框架中最常用的一个控件datagrid.在使用easyui框架时,datagrid是使用最多的控件,它不仅好用,关键是实用. 我为大家建立一个博客更新的 ...

  7. 从0开始学习 GitHub 系列之「03.Git 速成」

    前面的 GitHub 系列文章介绍过,GitHub 是基于 Git 的,所以也就意味着 Git 是基础,如果你不会 Git ,那么接下来你完全继续不下去,所以今天的教程就来说说 Git ,当然关于 G ...

  8. 从0开始学习 GitHub 系列之「01.初识 GitHub」----转载自stormzhang 原创文章

    1. 写在前面 我一直认为 GitHub 是程序员必备技能,程序员应该没有不知道 GitHub 的才对,没想到这两天留言里给我留言最多的就是想让我写关于 GitHub 的教程,说看了不少资料还是一头雾 ...

  9. 从0开始学习 GitHub 系列之「03.Git 速成」----转载自stormzhang 原创文章

    前面的 GitHub 系列文章介绍过,GitHub 是基于 Git 的,所以也就意味着 Git 是基础,如果你不会 Git ,那么接下来你完全继续不下去,所以今天的教程就来说说 Git ,当然关于 G ...

最新文章

  1. 【汇总】涉及iOSiPhone开发相关文章汇总
  2. 七自由度车辆稳定性数学模型和simulink求解
  3. arm linux 识别新硬盘_嵌入式Linux系列第13篇:USB摄像头拍照
  4. 中国语言文学专业c刊排行榜,中国有名的文学刊物有哪些 十大中国著名文学刊物盘点...
  5. zabbix db partition
  6. Oracle synonym 同义词
  7. ArchiMate - 发布【企业架构语言ArchiMate v0.5.pdf】
  8. 数字和为sum的方法数-01背包计数问题
  9. 对于整数数组类的算法的终极解决方案
  10. 判断大小_美人计 | 学会这招大小骨架判断法,我知道自己不是胖了
  11. 官方正式预热小米10S:哈曼卡顿加持小米有史以来音质最好的手机
  12. 做食品检测1年,自学软件测试,最后心惊胆战转行
  13. 珞珈一号夜间灯光数据评价
  14. 调用微软小冰API,实现批量人脸颜值打分
  15. 罗振宇2021跨年演讲3:谁能跳出数字化系统困境?
  16. 使用Markdown进行计划安排(打钩)
  17. python金额转换汉字为数字
  18. 新年礼品选超人气MID口袋电脑,不错的选择!
  19. linux 没有可用软件包,Linux中“没有可用的软件包XX,但是它被其他软件包引用”的解决方法...
  20. jQuery 用click() 失效,不起作用,直接父级使用on事件委托不好使

热门文章

  1. 约瑟夫问题(丢手帕问题)的java实现
  2. C#获取二叉树深度及分层遍历二叉树
  3. 阿里云Redis开发规范[转]
  4. Cocos2d-x V3.2+Cocos Studio1.6 实现一个简单的uibutton点击功能
  5. 实现数据库的增删改查
  6. 不做CIO 就做首席架构师
  7. 取得Servlet文件的絕對路徑;文件讀寫操作
  8. 关于cast类型转换后无法使用索引的优化
  9. Xposed是如何为所欲为的?
  10. android.view.WindowManager$BadTokenException: Unable to add window — token null