一步步学习汇编系列(7)
从访问内存的角度继续学习几个寄存器<?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 我们可以这样安排,但若要让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)相关推荐
- 一步步学习汇编(8)之指令
要理解ret,retf,call指令,必须要先理清以下汇编基础知识: 一. [bx]和内存单元<?xml:namespace prefix = o ns = " ...
- 【转】学习汇编前你应该知道的知识
转载地址:http://www.zxbc.cn/html/20070611/22772.html 1.汇编需要什么工具和程序,到哪里下载? 目前阶段,汇编程序仅需要两个程序就够了.masm.e ...
- 从0开始学习GitHub系列之「Git 速成」
从0开始学习GitHub系列之「Git 速成」 糖果果| 2016-06-24 10:55 浏览量(32) 评论(0) 推荐(0) 数据 小编注:[从0开始学习 GitHub]是一个系 ...
- 从0开始学习GitHub系列之「认识并加入GitHub」
从0开始学习GitHub系列之「认识并加入GitHub」 糖果果| 2016-06-16 16:01 浏览量(245) 评论(0) 推荐(0) 数据 小编注:[从0开始学习 GitHu ...
- 从0开始学习 GitHub 系列之「初识 GitHub」
## 1. 写在前面 我一直认为 GitHub 是程序员必备技能,程序员应该没有不知道 GitHub 的才对,没想到这两天留言里给我留言最多的就是想让我写关于 GitHub 的教程,说看了不少资料还是 ...
- 基于asp.net + easyui框架,一步步学习easyui-datagrid——界面(一)
从这篇博客,我会一步步的为大家讲解,easyui框架中最常用的一个控件datagrid.在使用easyui框架时,datagrid是使用最多的控件,它不仅好用,关键是实用. 我为大家建立一个博客更新的 ...
- 从0开始学习 GitHub 系列之「03.Git 速成」
前面的 GitHub 系列文章介绍过,GitHub 是基于 Git 的,所以也就意味着 Git 是基础,如果你不会 Git ,那么接下来你完全继续不下去,所以今天的教程就来说说 Git ,当然关于 G ...
- 从0开始学习 GitHub 系列之「01.初识 GitHub」----转载自stormzhang 原创文章
1. 写在前面 我一直认为 GitHub 是程序员必备技能,程序员应该没有不知道 GitHub 的才对,没想到这两天留言里给我留言最多的就是想让我写关于 GitHub 的教程,说看了不少资料还是一头雾 ...
- 从0开始学习 GitHub 系列之「03.Git 速成」----转载自stormzhang 原创文章
前面的 GitHub 系列文章介绍过,GitHub 是基于 Git 的,所以也就意味着 Git 是基础,如果你不会 Git ,那么接下来你完全继续不下去,所以今天的教程就来说说 Git ,当然关于 G ...
最新文章
- 【汇总】涉及iOSiPhone开发相关文章汇总
- 七自由度车辆稳定性数学模型和simulink求解
- arm linux 识别新硬盘_嵌入式Linux系列第13篇:USB摄像头拍照
- 中国语言文学专业c刊排行榜,中国有名的文学刊物有哪些 十大中国著名文学刊物盘点...
- zabbix db partition
- Oracle synonym 同义词
- ArchiMate - 发布【企业架构语言ArchiMate v0.5.pdf】
- 数字和为sum的方法数-01背包计数问题
- 对于整数数组类的算法的终极解决方案
- 判断大小_美人计 | 学会这招大小骨架判断法,我知道自己不是胖了
- 官方正式预热小米10S:哈曼卡顿加持小米有史以来音质最好的手机
- 做食品检测1年,自学软件测试,最后心惊胆战转行
- 珞珈一号夜间灯光数据评价
- 调用微软小冰API,实现批量人脸颜值打分
- 罗振宇2021跨年演讲3:谁能跳出数字化系统困境?
- 使用Markdown进行计划安排(打钩)
- python金额转换汉字为数字
- 新年礼品选超人气MID口袋电脑,不错的选择!
- linux 没有可用软件包,Linux中“没有可用的软件包XX,但是它被其他软件包引用”的解决方法...
- jQuery 用click() 失效,不起作用,直接父级使用on事件委托不好使
热门文章
- 约瑟夫问题(丢手帕问题)的java实现
- C#获取二叉树深度及分层遍历二叉树
- 阿里云Redis开发规范[转]
- Cocos2d-x V3.2+Cocos Studio1.6 实现一个简单的uibutton点击功能
- 实现数据库的增删改查
- 不做CIO 就做首席架构师
- 取得Servlet文件的絕對路徑;文件讀寫操作
- 关于cast类型转换后无法使用索引的优化
- Xposed是如何为所欲为的?
- android.view.WindowManager$BadTokenException: Unable to add window — token null