汇编语言(三)寄存器(内存访问)
<h1>内存访问</h1><h2 id="内存中字的存储">内存中字的存储</h2>
<p>在8086cpu中,一个字由两个字节单元组成。 <br>
字节单元,即存放一个字型数据(16位)的内存单元,由两个连续的内存单元组成。在8086中,高地址内存单元存放字型数据的高位字节,低地址存放字型数据的低位字节。 <br>
我们将起始位置位N的字单元简称位N地址字单元。</p>
<h2 id="DS和">DS和</h2>
<p>同样的cpu读取一个内存单元的时候。内存单元地址由基础地址(<code>段地址*10H</code>)+偏移地址组成。 <br>
其中DS段寄存器中存储内存单元的基础地址。而我们在访问内存单元时,只需要在指令中给出偏移地址即可。 <br>
如我们想要访问<code>220ff</code>地址空间的数据,将其移动到ax寄存器</p>
<div data-mode="asm">
<pre><code>mov ax,2200
mov ds,ax
mov ax,</code></pre>
</div>
<p>其中<code>ff</code>为偏移地址。同时要注意段寄存器可以使用mov命令,但是不能够使用直接量。只能使用另外一个寄存器进行中转。 <br>
这属于8086的硬件设计的问题。 <br>
还有<code>add</code> <code>sub</code> 命令的操作对象中也不能有段寄存器。</p>
<h2 id="字的传送">字的传送</h2>
<p>8086有16根数据总线,所以可以直接在16为寄存器中进行16位数据的传送。只需要给出字单元地址就可以了。</p>
<h1>mov、add、sub指令</h1>
<p>需要注意的是:</p>
<ol class="wiz-list-level1">
<li>mov可以对段寄存器进行操作,但是不能对<strong>CS(指令段寄存器进行操作)</strong>。</li>
<li>段寄存器都不能使用立即数</li>
<li>add,sub都不能将段寄存器作为操作对象之一</li>
</ol>
<h2 id="数据段">数据段</h2>
<h2 id="栈">栈</h2>
<p>栈是一种具有特殊的访问方式的存储空间。他的特殊性就在于,最后进入这个空间的数据,最先出去(LIFO,Last In First Out)。 <br>
<img title="" src="http://yanxuan.nosdn.127.net/282ee83938a5721f9e9df6d2b784dcbb.png" alt="UTOOLS1560075431035.png"> <br>
从程序化的角度来讲,需要一个标记,这个标记指示着栈顶。 <br>
栈的基本操作有两种,入栈(让如),出栈(取出)。</p>
<h2 id="cpu提供的栈机制">cpu提供的栈机制</h2>
<p>8086cpu提供了两个寄存器用来定义栈。其中段寄存器SS用来定义栈顶的基础地址,SP用来定义栈顶的偏移地址。 <br>
同样是:基础地址(段地址*10H)+偏移地址 <br>
同时汇编分别提供了push和pop命令。</p>
<ul>
<li>当调用push时:<ol class="wiz-list-level2">
<li>SP=SP-2</li>
<li>将数据送入SS:SP指向的字单元</li>
</ol></li>
<li>当调用pop时:<ol class="wiz-list-level2">
<li>将SS:SP指向字单元的数据送入指定空间</li>
<li>SP=SP+2 <br>
栈操作都是以字位单位的</li>
</ol></li>
</ul>
<h2 id="栈顶越界的问题">栈顶越界的问题</h2>
<p>我们知道8086只是提供了指示栈顶的SS,SP寄存器,并提供了push,pop指令。但是这样就存在了一个问题,我们不知道栈的边界。所以很容易造成越界的操作。</p>
<h2 id="push,pop指令">push,pop指令</h2>
<p>这两个指令,实际上就是一种内存传送指令。可以发现,他在任何时候,指令都只会做以下三种操作:</p>
<ol class="wiz-list-level1">
<li>将内存的数据送入栈(内存)/将栈(内存)的数据送入寄存器</li>
<li>更改SP寄存器的值 <br>
同时可以很了解到栈的最大大小,因为SP为16位寄存器。所以栈顶的变化范围最大位0~FFFFH。也就是64KB。</li>
</ol>
<h2 id="段的概述">段的概述</h2>
<p>我们可以将一段连续的内存定义位一个段,用一个段地址只是段,用偏移地址访问段地单元。关于段,这是我们自己的定义安排,实际并没有这样的东西。 <br>
到目前位置我们知道的有:</p>
<ul>
<li>代码段</li>
<li>数据段</li>
<li>栈段</li>
</ul>
<p>同时安排cpu来放问这些段:</p>
<ul>
<li>对于数据段,将其段地址放入DS,在指令中使用偏移地址来访问</li>
<li>对于代码段,将其段地址放入CS,并将第一条指令的偏移地址放入SP。cpu自动执行。</li>
<li>对于栈段,将其段地址放入SS,并将栈顶单元的偏移地址放在SP中 <br>
所以我们可以得出内存中的指令和数据并没有什么区别,实际上在内存中并没有什么意思。关键在于cpu对其的处理。对于汇编语言来讲,也就是cpu中寄存器的设置,即CS,IP,SS,SP,DS的指向。</li>
</ul>
<h2 id="实验小结">实验小结</h2>
<p>Debug中对于D,E,A,U命令可以使用段寄存器来代替基础地址。 <br>
在Debug时,执行修改栈寄存器的指令以后不会停止执行,而是会将紧接的下一条指令执行。 <br>
涉及:中断机制。</p>
<h1> </h1>
<div id="wiz-table-col-line" style="display: none"> </div>
<div id="wiz-table-row-line" style="display: none"> </div>
<div id="wiz-table-range-border_start" style="display: none"> </div>
<div id="wiz-table-range-border_range" style="display: none"> </div>
<h1><br><br></h1>
<div>来自为知笔记(Wiz)</div>
<h1 id="mov、add、sub指令"><br><br></h1><br><br>
来源:https://www.cnblogs.com/freesfu/p/10994261.html
頁:
[1]