汇编语言全梳理(精简版)
<h2><span style="color: rgba(0, 0, 128, 1)">寄存器一览</span></h2><ul>
<li><strong>通用寄存器</strong>
<ul>
<li>ax,bx,cx,dx,(ah,al,bh,bl,ch,cl,dh,dl)</li>
<li>sp,bp,si,di</li>
</ul>
</li>
<li><strong>指令寄存器</strong>
<ul>
<li>ip</li>
</ul>
</li>
<li><strong>标志寄存器</strong>
<ul>
<li>FR</li>
</ul>
</li>
<li><strong>段寄存器</strong>
<ul>
<li>cs,ds,ss,es</li>
</ul>
</li>
</ul>
<p> </p>
<h2><span style="color: rgba(0, 0, 128, 1)"><strong>mov</strong></span></h2>
<table border="0">
<tbody>
<tr>
<td><span style="font-size: 14px"><strong>指令</strong></span></td>
<td><span style="font-size: 14px"><strong>示例</strong></span></td>
</tr>
<tr>
<td><span style="font-size: 14px">mov 寄存器, 数据</span></td>
<td><span style="font-size: 14px">mov ax, 8</span></td>
</tr>
<tr>
<td><span style="font-size: 14px">mov 寄存器, 寄存器</span></td>
<td><span style="font-size: 14px">mov ax, bx</span></td>
</tr>
<tr>
<td><span style="font-size: 14px">mov 寄存器, 内存</span></td>
<td>
<p><span style="font-size: 14px">mov ax, </span></p>
<p><span style="font-size: 14px">mov ax, </span></p>
</td>
</tr>
<tr>
<td><span style="font-size: 14px">mov 内存, 寄存器</span></td>
<td>
<p><span style="font-size: 14px">mov , ax</span></p>
<p><span style="font-size: 14px"><span style="font-size: 14px"><span style="font-size: 14px">mov , ax</span></span></span></p>
</td>
</tr>
</tbody>
</table>
<p>内存地址由 段地址:偏移地址 决定,8086 选择 ds 段寄存器作为默认的段地址</p>
<p>由于段寄存器也是寄存器,除了硬件规定<strong>不能直接将数据 mov 到段寄存器</strong>之外,其他的和正常寄存器一样</p>
<table border="0">
<tbody>
<tr>
<td><span style="font-size: 14px"><strong>指令</strong></span></td>
<td><span style="font-size: 14px"><strong>示例</strong></span></td>
</tr>
<tr>
<td><span style="font-size: 14px">mov 段寄存器, 寄存器</span></td>
<td><span style="font-size: 14px">mov ds, ax</span></td>
</tr>
<tr>
<td><span style="font-size: 14px">mov 寄存器, 段寄存器<br></span></td>
<td><span style="font-size: 14px">mov ax, ds</span></td>
</tr>
<tr>
<td><span style="font-size: 14px">mov 段寄存器, 内存</span></td>
<td><span style="font-size: 14px">mov ds, </span></td>
</tr>
<tr>
<td><span style="font-size: 14px">mov 内存, 段寄存器</span></td>
<td><span style="font-size: 14px">mov , ds</span></td>
</tr>
</tbody>
</table>
<p>变种</p>
<ul>
<li><strong>mov ax, 'a'</strong>:处理字符</li>
<li><strong>mov ax, </strong>:可用作数组操作</li>
<li><strong>mov ax, </strong></li>
<li><strong>mov ax, </strong></li>
<li><strong>mov word ptr ,1</strong>:指定长度为一个字</li>
<li><strong>mov byte ptr ds:, 1</strong>:指定长度为一个字节</li>
</ul>
<p> </p>
<h2><span style="color: rgba(0, 0, 128, 1)"><strong>add / sub</strong></span></h2>
<p> 格式同 mov 一样 </p>
<p> </p>
<h2><span style="color: rgba(0, 0, 128, 1)"><strong>mul</strong></span></h2>
<p><span style="color: rgba(0, 0, 0, 1)"><strong>计算</strong>:其中一个乘数放在 al 或 ax 中,另一个看指令</span></p>
<ul>
<li><strong>mul reg</strong></li>
<li><strong>mul 内存单元</strong></li>
</ul>
<p><span style="color: rgba(0, 0, 0, 1)"><strong>结果</strong>:8位相乘结果放在 ax 中,16位相乘结果放在(高位dx 地位ax)中</span></p>
<p> </p>
<h2><strong><span style="color: rgba(0, 0, 128, 1)">div</span></strong></h2>
<ul>
<li><strong>div 寄存器</strong></li>
<li><strong>div 内存单元</strong></li>
</ul>
<p>除数为 8 位</p>
<table border="0">
<tbody>
<tr>
<td style="text-align: center"> </td>
<td style="text-align: center" colspan="2"><strong>ax</strong></td>
<td style="text-align: center"><strong>dx</strong></td>
</tr>
<tr>
<td style="text-align: center"> </td>
<td style="text-align: center"><strong>ah</strong></td>
<td style="text-align: center"><strong>al</strong></td>
<td style="text-align: center"> </td>
</tr>
<tr>
<td style="text-align: center"><strong>计算时</strong></td>
<td style="text-align: center" colspan="2">被除数全部 16 位</td>
<td style="text-align: center"> </td>
</tr>
<tr>
<td style="text-align: center"><strong>结果</strong></td>
<td style="text-align: center">商</td>
<td style="text-align: center">余数</td>
<td style="text-align: center"> </td>
</tr>
</tbody>
</table>
<p> </p>
<p>除数为 16 位</p>
<table border="0">
<tbody>
<tr>
<td style="text-align: center"> </td>
<td style="text-align: center" colspan="2"><strong>ax</strong></td>
<td style="text-align: center"><strong>dx</strong></td>
</tr>
<tr>
<td style="text-align: center"><strong>计算时</strong></td>
<td style="text-align: center" colspan="2">被除数低 16 位</td>
<td style="text-align: center">被除数高 16 位 </td>
</tr>
<tr>
<td style="text-align: center"><strong>结果</strong></td>
<td style="text-align: center" colspan="2">商</td>
<td style="text-align: center">余数 </td>
</tr>
</tbody>
</table>
<p> </p>
<h2><strong><span style="color: rgba(0, 0, 128, 1)">寻址方式总结</span></strong></h2>
<p><img src="https://img2020.cnblogs.com/blog/1096103/202009/1096103-20200913231311075-1004567800.png" alt="" width="743" height="679" loading="lazy"></p>
<p> </p>
<h2><span style="color: rgba(0, 0, 128, 1)"><strong>push / pop</strong></span></h2>
<p>CPU 取 SS:SP 作为栈顶地址,我们可以自己初始化栈顶地址为 10010H</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ax, 1000H
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ss, ax
</span><span style="color: rgba(0, 0, 255, 1)">mov</span> sp, 0010H</pre>
</div>
<table border="0">
<tbody>
<tr>
<td><strong><span style="font-size: 14px">指令</span></strong></td>
<td><strong><span style="font-size: 14px">步骤</span></strong></td>
</tr>
<tr>
<td>push ax</td>
<td>
<p>SP = SP - 2</p>
<p>ax 内容送入栈顶的内存地址</p>
</td>
</tr>
<tr>
<td>pop ax</td>
<td>
<p>栈顶的内存地址的内容送入 ax</p>
<p>SP = SP + 2</p>
</td>
</tr>
<tr>
<td>push/pop 段寄存器</td>
<td>
<p>同理</p>
</td>
</tr>
<tr>
<td>push/pop 内存单元</td>
<td>
<p>同理</p>
</td>
</tr>
</tbody>
</table>
<p>另外:<strong>pushf</strong> 和 <strong>popf</strong> 表示将标志寄存器的值压栈和出栈 </p>
<p> </p>
<h2><span style="color: rgba(0, 0, 128, 1)"><strong>loop</strong></span></h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span> ax, <span style="color: rgba(128, 0, 128, 1)">2</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> cx, <span style="color: rgba(128, 0, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">s:</span> <span style="color: rgba(0, 0, 255, 1)">add</span><span style="color: rgba(0, 0, 0, 1)"> ax, ax
loop s</span></pre>
</div>
<p><strong>loop s</strong> 表示:</p>
<ol>
<li>cx = cx - 1</li>
<li>如果 cx 为 0 则继续执行下面的指令</li>
<li>如果 cx 不为 0 则跳转到标号 s 处</li>
</ol>
<p> </p>
<h2><strong><span style="color: rgba(0, 0, 128, 1)">定义不同的段,标准示例</span></strong></h2>
<div class="cnblogs_code">
<pre>assume <span style="color: rgba(0, 128, 128, 1)">cs:</span>code, <span style="color: rgba(0, 128, 128, 1)">ds:</span>data, <span style="color: rgba(0, 128, 128, 1)">ss:</span><span style="color: rgba(0, 0, 0, 1)">stack
data segment
dw 0001h, 0002h, ... 000fh
data ends
stack segment
dw </span><span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span> ... <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
stack ends
code segment
</span><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">定义数据段</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ax, <strong>data
</strong></span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ds, ax
</span><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">定义栈段</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ax, <strong>stack
</strong></span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ss, ax
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> sp, 20h
...
code ends
end</span></pre>
</div>
<p> </p>
<h2><strong><span style="color: rgba(0, 0, 128, 1)">and / or<br></span></strong></h2>
<ul>
<li><strong>and al, 10110010B</strong>:逻辑与</li>
<li><strong>or al, 10110010B</strong>:逻辑或
<h3> </h3>
</li>
</ul>
<h2><strong><span style="color: rgba(0, 0, 128, 1)">db dw dd dup</span></strong></h2>
<ul>
<li><strong>db</strong>:定义字节型数据</li>
<li><strong>dw</strong>:定义字型数据</li>
<li><strong>dd</strong>:定义双字型数据</li>
<li><strong>dup</strong>
<ul>
<li><strong>db 3 dup (0)</strong> 相当于 db 0,0,0</li>
<li><strong>db 3 dup (1,2)</strong> 相当于 db 1,2,1,2,1,2</li>
</ul>
</li>
</ul>
<p> </p>
<h2><span style="color: rgba(0, 0, 128, 1)">跳转指令</span></h2>
<p><span style="color: rgba(0, 0, 128, 1)">jump 类型</span></p>
<ul>
<li><strong>jump short 标号</strong>:根据相对位移跳转 IP = IP + 8 位位移</li>
<li><strong>jump near ptr 标号</strong>:IP = IP + 16 位位移</li>
<li><strong>jump far ptr 标号</strong>:CS = 标号所在段的段地址;IP = 标号在段中的偏移地址</li>
<li><strong>jump 16位reg</strong>:转移地址在寄存器中 IP = (reg)</li>
<li><strong>jump word ptr 内存</strong>:IP = (内存)</li>
<li><strong>jump dword ptr 内存</strong>:CS = (内存+2);IP = (内存)</li>
<li><strong>jcxz 标号</strong>:(cx) == 0 时,(IP) = (IP) + 8 位位移</li>
</ul>
<p><span style="color: rgba(0, 0, 128, 1)">call 和 ret / iret 类型</span></p>
<ul>
<li><strong>ret</strong>:形象解释相当于<span style="color: rgba(0, 0, 255, 1)"> pop IP</span>
<ul>
<li>(IP) = ((ss) * 16 + (sp))</li>
<li>(sp) = (sp) + 2</li>
</ul>
</li>
<li><strong>retf</strong>:形象解释相当于 <span style="color: rgba(0, 0, 255, 1)">pop IP;pop CS</span>
<ul>
<li>(IP) = ((ss) * 16 + (sp))</li>
<li>(sp) = (sp) + 2</li>
<li>(CS) = ((ss) * 16 + (sp))</li>
<li>(sp) = (sp) + 2</li>
</ul>
</li>
<li><strong>iret</strong>:形象解释相当于 <span style="color: rgba(0, 0, 255, 1)">pop IP;pop CS;popf</span></li>
<li><strong>call 标号</strong>:形象解释相当于 <span style="color: rgba(0, 0, 255, 1)">push IP;jmp near ptr 标号</span>
<ul>
<li>(sp) = (sp) - 2</li>
<li>((ss) * 16 + (sp)) = (IP)</li>
<li>(IP) = (IP) + 16 位位移</li>
</ul>
</li>
<li><strong>call far ptr 标号</strong>:形象解释相当于 <span style="color: rgba(0, 0, 255, 1)">push CS;push IP;jmp near ptr 标号</span></li>
<li><strong>call 16位reg</strong>:形象解释相当于 <span style="color: rgba(0, 0, 255, 1)">push IP;jmp 16位reg</span></li>
<li><strong>call word ptr 内存单元</strong>:形象解释相当于<span style="color: rgba(0, 0, 255, 1)"> push IP;jmp word ptr</span></li>
</ul>
<p><span style="color: rgba(0, 0, 128, 1)">子程序标准模板</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">子程序中使用的寄存器入栈
子程序内容
子程序中使用的寄存器出栈
返回(ret、retf)</span></pre>
</div>
<p> </p>
<h2><span style="color: rgba(0, 0, 128, 1)"><strong>rep movsb</strong></span></h2>
<ul>
<li>传送的源地址:<strong>ds:si</strong></li>
<li>传送的目的地址:<strong>es:di</strong></li>
<li>传输长度:<strong>cs</strong></li>
<li>传输方向:<strong>cld </strong>为正向</li>
</ul>
<p> </p>
<h2><span style="color: rgba(0, 0, 128, 1)">端口读取</span></h2>
<ul>
<li><strong>in al, 20h</strong></li>
<li><strong>out 20h, al</strong></li>
</ul>
<p>如 CMOS 有两个端口,70h 是地址端口,71h 是数据端口,所以要读取 CMOS 某存储单元处(2)的数据,就要</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span> al, <span style="color: rgba(128, 0, 128, 1)">2</span>
<span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)"> 70h, al
</span><span style="color: rgba(0, 0, 255, 1)">in</span> al, 71h</pre>
</div>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
<p>公众号 - 低并发编程</p>
<div align="center" style="float:left;margin:30px"><img width="400px" src="https://images.cnblogs.com/cnblogs_com/flashsun/1878561/o_201113062734%E5%85%AC%E4%BC%97%E5%8F%B7%E4%BA%8C%E7%BB%B4%E7%A0%81.jpg"> </div><br><br>
来源:https://www.cnblogs.com/flashsun/p/13663050.html
頁:
[1]