非特权阶层 發表於 2020-10-20 12:43:00

汇编语言-寻址方式-地址和数据相关的寻址方式

<h2 class="md-end-block md-heading"><span class="md-plain md-expand">数据相关的寻址方式</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">1 立即寻址方式</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">直接使用立即数来处理</span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>mov al,5<br><span>mov ax,3064H</span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">2 寄存器寻址方式</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">操作数在寄存器中,直接使用寄存器赋值来读取内部的操作数。</span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">另外的方式的简介:</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">在8086中把操作数的偏移地址称为有效地址,以下的操作都是取得有效地址(EA)的不同途径。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">有效地址可以由以下四种成分:</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">位移量(displacement):存放的是一个地址。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">基址(base):基址部分,通常用来指数据段中数据或字符串的首地址</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">变址(index):存放在变址寄存器中的内容。通常用来访问数组中的某个元素或字符串的某个字符。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">比例因子(scale factor):是386新增加的寻址方式的术语,值可为1,2,4,8在寻址中,可用变址寄存器内容乘以比例因子来取得变址值。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">有效地址的计算公式可用由以下来处理:</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">EA = 基址 + (变址 X 比例因子) + 位移量</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">除了比例因子固定,其它三个都可以有正负。</span></span></p>
<table class="md-table">
<thead>
<tr class="md-end-block"><th><span class="td-span"><span class="md-plain">四种成分</span></span></th><th><span class="td-span"><span class="md-plain">16位寻址</span></span></th><th><span class="td-span"><span class="md-plain">32位寻址</span></span></th></tr>
</thead>
<tbody>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">位移量</span></span></td>
<td><span class="td-span"><span class="md-plain">0,8,16位</span></span></td>
<td><span class="td-span"><span class="md-plain">0,8,32位</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">基址寄存器</span></span></td>
<td><span class="td-span"><span class="md-plain">BX,BP</span></span></td>
<td><span class="td-span"><span class="md-plain">任何32位通用寄存器</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">变址寄存器</span></span></td>
<td><span class="td-span"><span class="md-plain">SI,DI</span></span></td>
<td><span class="td-span"><span class="md-plain">除ESP外的32位通用寄存器</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">比例因子</span></span></td>
<td><span class="td-span"><span class="md-plain">无</span></span></td>
<td><span class="td-span"><span class="md-plain">1,2,4,8</span></span></td>
</tr>
</tbody>
</table>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">表格一</span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">默认段选择规则</span></span></p>
<table class="md-table">
<thead>
<tr class="md-end-block"><th><span class="td-span"><span class="md-plain">访存类型</span></span></th><th><span class="td-span"><span class="md-plain">所用段及段寄存器</span></span></th><th><span class="td-span"><span class="md-plain">却省选择规则</span></span></th></tr>
</thead>
<tbody>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">指令</span></span></td>
<td><span class="td-span"><span class="md-plain">代码段 CS寄存器</span></span></td>
<td><span class="td-span"><span class="md-plain">用于取指</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">堆栈</span></span></td>
<td><span class="td-span"><span class="md-plain">堆栈段 SS寄存器</span></span></td>
<td><span class="td-span"><span class="md-plain">所有的堆栈的进栈和出栈,任何用ESP或EBP作为基址寄存器的访问</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">局部数据</span></span></td>
<td><span class="td-span"><span class="md-plain">数据段 DS寄存器</span></span></td>
<td><span class="td-span"><span class="md-plain">除相对于堆栈以及串处理指令的目的以外的所有数据访问</span></span></td>
</tr>
<tr class="md-end-block">
<td><span class="td-span"><span class="md-plain">目的串</span></span></td>
<td><span class="td-span"><span class="md-plain">附加数据段 ES寄存器</span></span></td>
<td><span class="td-span"><span class="md-plain">串处理指令的目的串</span></span></td>
</tr>
</tbody>
</table>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">表格二</span></span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">3 直接寻址方式</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">操作数的有效地址只包含位移量这一种成分。值就在代码段中指令的操作码之后。也就是位移量就是操作数的有效地址。</span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>;假设(ds) = 3050H<br><span>mov ax,<span class="cm-tab">   ;就是把内存在3050:0000内存的数据传送到ax中<br><span>也可以用符号地址代替数值地址比如<br><span>mov ax,;就是把value的3050:value将value替换为数据跟上一样<br><span><span>​<br><span><span>​<br></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">也可以用指定段寄存器来作为段地址也是可以的。</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>mov ax,es:value<br><span>mov ax,es:</span></span></pre>
<h3 class="md-end-block md-heading"><span class="md-plain">4 寄存器间接寻址方式</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">操作数的有效地址只包含基址寄存器或变址寄存器的一种,有效地址就在某个寄存器里。如表格一所示在16位寻址时可用的基址寄存器位BP和BX,变址寄存器位SI和DI。在32位寻址时可用使用EAX,EBX,ECX,EDX,ESP,EBP等BSI,EDI等八个通用寄存器。凡是使用BP,ESP和EBP的默认段位SS,其它寄存器的默认段位DS寄存器。</span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>;例子<br><span>;(DS) = 2000H (BX) = 1000H<br><span>mov ax,<br><span>;则物理地址等于2000*16+bx=21000<br><span>;则就是把地址位于21000的数据送给ax中<br><span><span>​</span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">同样也可以跨越前端来处理</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">mov ax,es:<span class="md-tab"> <span class="md-plain">;也是可以处理的</span></span></span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">5 寄存器相对寻址方式(register relative addressing)</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">操作数的有效地址为基址寄存器或变址寄存器的内容和指令中指定的位移量之和。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">EA(有效地址)= (base(基址)||index(变址)) +displacement (位移量)</span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>;例子<br><span>mov ax,count<br><span>;和mov ax,是一个意思<br><span>;同样也可以使用跨段来访问<br><span>mov dl,es:string</span></span></span></span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">6 基址变址寻址方式</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">EA = base + index</span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>mov ax,<br><span>;或者<br><span>mov ax,<br><span>;同样可以使用段跨越前缀<br><span>mov ax,es:</span></span></span></span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">7 相对基址变址寻址方式</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">EA = base + index +displacement</span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>mov ax,mask<br><span>;也可以写成<br><span>mov ax,mask<br><span>;或者<br><span>mov ax,</span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">这种寻址方式常用来对于二维数组的寻址。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">8 比例变址寻址方式(scaled indexed addressing)</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">EA = displacement + index*比例</span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>;例子<br><span>mov ecx,count</span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">9 基址比例变址寻址方式(based scaled indexed addressing)</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">操作数的有效地址是变址寄存器*比例因子加上基址</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">EA = base+index*比例因子</span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>MOV ECX,</span></pre>
<h3 class="md-end-block md-heading"><span class="md-plain">10 相对基址比例变址寻址方式</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">EA = base+index*比例因子+displacement</span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>MOV EAX,TABLE</span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">与地址有关的寻址方式</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">1<span class="md-tab"> <span class="md-plain">段内直接寻址</span></span></span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">转向的有效地址是当前IP寄存器的内容和指令中指定的8位或16位位<span><strong>移量之和</strong><span class="md-plain">。</span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">这种方式的转向有效地址用相当于当前IP值的位移量来表示。位移量是转向的有效地址与当前IP值之差。当这一段程序在内存中的不同区域运行时,之中寻址方式的转移指令本身不会发生变化。这种寻址方式适用于<span><strong>条件转移</strong><span class="md-plain">和无条件转移指令。但是当用于条件转移指令时,位移量只允许8位(386和后继机型可以为8位或32位)</span></span></span></span></p>
<p class="md-end-block md-p"><img src="https://img2020.cnblogs.com/blog/1940490/202010/1940490-20201020125856905-1126208094.png"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">无条件转移指令在位移量为8时称为短跳转,位移量为16时称为近跳转。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">指令格式:</span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>JMP NEAR PTR PROGIA<br><span>JMP SHORT QUEST<br><span>;在汇编指令中如果位移量为16位则在符号地址前加操作符NEAR PTR<br><span>;如果位移量为8位,就在前面添加操作符SHORT</span></span></span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">2<span class="md-tab"> <span class="md-plain">段内间接寻址(intrasegment indirect addressing)</span></span></span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">转向有效地址是一个个寄存器或者是一个存储单元的内容,这个寄存器或存储单元的内容可以用数据寻址方式中除立即数以外的任何一种寻址方式取得。所得到的转向的有效地址用来取代IP寄存器的内容。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">这种寻址方式和下面的两种都不能用在条件转移指令上。<span><strong>也就是条件转移指令只能使用段内直接寻址的8位位移量</strong><span class="md-plain">(当然在386以及后面的机型中运行8位或32位位移量)JMP和CALL指令可用四种寻址方式的任何一种。</span></span></span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>;段内间接寻址方式的汇编格式<br><span>JMP BX<br><span>JMP WORD PTR<br><span>;里面的WORD PTR是操作符,用以指出后面的寻址方式所取得的转地址是一个字的有效地址</span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">段内间接寻址和段内直接寻址都是段内转移,直接把求得的转向有效地址送到IP寄存器里。</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>;假设DS=2000,BX=1256,SI=528F<br><span>;位移量=20A1H (232F7)=3280 (264E5) = 2450<br><span><span>​<br><span>JMP BX;执行指令后IP=1256<br><span><span>​<br><span>JMP TABLE ;执行指令后IP=(16*DS+BX+位移量)=232F7<br><span><span>​<br><span>JMP ;执行指令后ip = (16xDS+BX+SI) = 2450</span></span></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">3 段间直接寻址</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">在指令中直接提供转向段地址和偏移地址,只要用指令中指定的偏移地址取代IP寄存器的内容,用指令中指定的段地址取代CS寄存器的内容,就完成了一个从一个段到另一个段的转移操作。</span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>;指令的汇编语言格式可表示位<br><span>JMP FAR PTR NEXTROUTINT<br><span>;其中,NEXTROUTINT为转向的符号地址,FAR PTR则是表示段间转移的操作符</span></span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">4 段间间接寻址(intersegment indirect addressing)</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">用存储器中的两个相继字的内容来取代IP和CS寄存器中的原始内容,以达到段间转移的目的。这里,存储单元的地址是由指令指定除立即数方式和寄存器方式意外的任何一种数据寻址方式获得。</span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>;这种指令的汇编语言格式可以表示为<br><span>JMP<span class="cm-tab"> DWORD PTR<br><span>;其中说明数据寻址方式为直接变址寻址方式,DWORD PTR为双字操作符,说明转向地址需取双字为段间转移指令。</span></span></span></span></pre>
<p><span>&nbsp;</span></p><br><br>
来源:https://www.cnblogs.com/Sna1lGo/p/13845861.html
頁: [1]
查看完整版本: 汇编语言-寻址方式-地址和数据相关的寻址方式