解放日本活捉高市 發表於 2022-10-28 09:52:00

汇编语言-8086指令(上)

<h1 class="md-end-block md-heading"><span class="md-plain md-expand">数据传送指令</span></h1>
<p class="md-end-block md-p"><span class="md-plain">汇编语言中字母开头通常表示标识符(如常量、变量、标号),所以MASM规定十六进制数如果以字母开头需要添加前导0。</span></p>
<p class="md-end-block md-p"><span class="md-plain">当目的操作数是存储单元,而源操作数既可以是字又可以是字节时,必须显式指明字节传送还是字传送,btye ptr or word ptr。</span></p>
<p class="md-end-block md-p"><span class="md-plain">不允许段寄存器和段寄存器、段寄存器和立即数、以及存储单元和存储单元之间的数据传送,CS寄存器通过数据传送进行修改。</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">目的操作数和源操作数的类型必须一致。</span></p>
<p class="md-end-block md-p md-focus">&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">传送指令<span class="md-pair-s "><strong>Mov</strong></span></span></h3>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-keyword">mov <span class="cm-keyword">reg/mem, imm <span class="cm-comment">; 立即数传送<br><span><span class="cm-keyword">mov <span class="cm-keyword">reg/mem/seg reg <span class="cm-comment">; 寄存器传送<br><span><span class="cm-keyword">mov <span class="cm-keyword">reg/seg mem <span class="cm-comment">; 存储单元传送<br><span><span class="cm-keyword">mov <span class="cm-keyword">reg/mem seg <span class="cm-comment">; 段寄存器传送 </span></span></span></span></span></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">交换指令<span class="md-pair-s "><strong>XCHG</strong></span></span></h3>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-keyword">xchg <span class="cm-keyword">reg, reg/mem<br><span><span class="cm-keyword">xchg <span class="cm-keyword">reg/mem</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">换码指令<span class="md-pair-s "><strong>XLAT</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">bx指定段地址,al指定偏移地址,的数据存储在al中</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-keyword">xlat <span class="cm-keyword">label <span class="cm-comment">; 和第二种写法的效果是一样的,只不过这个可以明确说明缓冲区所在逻辑段的位置<br><span><span class="cm-keyword">xlat <span class="cm-comment">; al&lt;-ds:</span></span></span></span></span></span></span></pre>
<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">进栈指令<span class="md-pair-s "><strong>PUSH</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">进栈指令先使堆栈指针(sp)减2,然后将一个字操作数存入堆栈顶部。(小端存储)</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-keyword">push <span class="cm-keyword">r16/m16/seg </span></span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">出栈指令<span class="md-pair-s "><strong>POP</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">出栈指令先将一个数传送至目的操作数,然后将堆栈指针(sp)加2</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-keyword">pop <span class="cm-keyword">r16/m16/seg</span></span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-plain">堆栈基址指针bp默认与堆栈段寄存器ss配合,利用堆栈可以实现主、子程序传递参数、现场的保护和恢复以及其它汇编指令的实现等等。</span></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">标志送AH指令<span class="md-pair-s "><strong>LAHF</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">将状态标志位传送至AH</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-keyword">lahf</span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">AH送标志指令<span class="md-pair-s "><strong>SAHF</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">将AH传送至状态标志位</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-keyword">sahf</span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">标志进栈指令<span class="md-pair-s "><strong>PUSHF</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">堆栈指针sp减2,将状态标志位传送入栈中</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-keyword">pushf</span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">标志出栈指令<span class="md-pair-s "><strong>POPF</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">将栈顶字单元传送入标志寄存器,堆栈指针sp加2</span></p>
<pre class="md-fences mock-cm md-end-block">popf</pre>
<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-plain">cl:复位,复0</span></p>
<p class="md-end-block md-p"><span class="md-plain">st:置位,置1</span></p>
<pre class="md-fences mock-cm md-end-block">; cf 进位标识<br>clc<br>stc<br>; df 方向标识<br>cld<br>std<br>; if 中断标识<br>cli<br>sti</pre>
<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">有效地址传送指令<span class="md-pair-s "><strong>LEA</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">有效地址:ea</span></p>
<p class="md-end-block md-p"><span class="md-plain">lea指令将存储单元的有效地址ea传送到指定寄存器</span></p>
<pre class="md-fences mock-cm md-end-block">lea r16, mem</pre>
<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-plain">LDS、LES指令分别将主存中mem指定的字送至R16,再将mem的下一个字送到ds或es。</span></p>
<p class="md-end-block md-p"><span class="md-plain">其中si的默认段寄存器为ds(ds:si),di的默认段寄存器为es(es:di)</span></p>
<pre class="md-fences mock-cm md-end-block">lds r16 mem<br>les r16 mem</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h1 class="md-end-block md-heading"><span class="md-plain">算术运算类指令</span></h1>
<h2 class="md-end-block md-heading"><span class="md-plain">状态标志</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">进位标志CF(Carry Flag)</span></h3>
<p class="md-end-block md-p"><span class="md-pair-s"><span class="md-plain">无符号数</span><span class="md-plain">加减运算结果的最高有效位有进位(加法)或借位(减法)时,CF=1;若没有,则CF=0。</span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">溢出标志OF(Overflow Flag)</span></h3>
<p class="md-end-block md-p"><span class="md-plain">回忆:补码的加减运算</span></p>
<p class="md-end-block md-p"><span class="md-plain">X(补)+ Y(补)= (X + Y)补</span></p>
<p class="md-end-block md-p"><span class="md-plain">X(补)+ Y(变补)= (X - Y)补</span></p>
<p class="md-end-block md-p"><span class="md-plain">变补:连同符号位取反加一</span></p>
<p class="md-end-block md-p"><span class="md-pair-s"><span class="md-plain">有符号数</span><span class="md-plain">加减结果超出范围时,OF=1;若没有,则OF=0。</span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">零标志ZF(Zero Flag)</span></h3>
<p class="md-end-block md-p"><span class="md-plain">运算结果为零时,ZF=1;若不为零,则ZF=0。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">符号标志SF(Sign Flag)</span></h3>
<p class="md-end-block md-p"><span class="md-plain">运算结果的最高位为1时,SF=1;若最高位为0,则SF=0。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">奇偶标志(Parity Flag)</span></h3>
<p class="md-end-block md-p"><span class="md-pair-s"><span class="md-plain">最低八位</span><span class="md-plain">的运算结果中,1的个数为偶数或零时,PF=1;若1的个数为奇数,则PF=0。</span></span></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">加法指令<span class="md-pair-s "><strong>ADD</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">源操作数和目的操作数相加,结果送到目的操作数</span></p>
<pre class="md-fences mock-cm md-end-block">add reg, imm/reg/mem<br>add word/byte ptr mem imm/reg</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">带进位加法指令<span class="md-pair-s "><strong>ADC</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">源操作数和目的操作数相加再加CF,结果送到目的操作数</span></p>
<pre class="md-fences mock-cm md-end-block">adc reg, imm/reg/mem<br>adc word/ptr mem, imm/reg</pre>
<p class="md-end-block md-p"><span class="md-plain">实现无符号双字加法运算,默认ax低位,dx存高位,合计32位</span></p>
<pre class="md-fences mock-cm md-end-block">mov ax, 4652h ; ax = 4652h<br>add ax, 0f0f0h ; ax = 3742h, cf = 1<br>mov dx, 0234h ; dx = 0234h<br>adc dx, 0f0f0h ; dx = f325h, cf = 0</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">增量指令<span class="md-pair-s "><strong>INC</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">操作数自增1</span></p>
<pre class="md-fences mock-cm md-end-block">inc reg<br>inc byte/word ptr mem</pre>
<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">减法指令<span class="md-pair-s "><strong>SUB</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">源操作数和目的操作数相减,结果送到目的操作数</span></p>
<pre class="md-fences mock-cm md-end-block">sub reg, imm/reg/mem<br>sub byte/word ptr mem, imm/reg</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">带借位减法指令<span class="md-pair-s "><strong>SBB</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">源操作数和目的操作数相加再减CF,结果送到目的操作数</span></p>
<pre class="md-fences mock-cm md-end-block">adc reg, imm/reg/mem<br>adc word/ptr mem, imm/reg</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">减量指令<span class="md-pair-s "><strong>DEC</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">操作数自减</span></p>
<pre class="md-fences mock-cm md-end-block">dec reg<br>dec byte/word ptr mem</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">求补指令<span class="md-pair-s "><strong>NEG</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">对操作数进行求补运算,对于计算机而言,即用零减去操作数;对于人而言,即操作数取反加1。</span></p>
<pre class="md-fences mock-cm md-end-block">neg reg<br>neg byte/word ptr mem</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">比较指令<span class="md-pair-s "><strong>CMP</strong></span></span></h3>
<p class="md-end-block md-p"><span class="md-plain">与减法指令基本相同,不同点是它不会把结果返回给目的操作数。</span></p>
<pre class="md-fences mock-cm md-end-block">cmp reg, imm/reg/mem<br>cmp byte/word ptr imm/reg</pre>
<p class="md-end-block md-p"><span class="md-plain">比较AL是否大于100</span></p>
<pre class="md-fences mock-cm md-end-block">cmp al, 100 <br>jb below ; al &lt; 100, 跳转到below<br>jump else ; al &gt;= 100, 跳转到else </pre>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">乘法指令<span class="md-pair-s "><strong>MUL/IMUL</strong></span></span></h2>
<p class="md-end-block md-p"><span class="md-plain">无符号数乘法指令MUL,有符号数乘法指令IMUL。</span></p>
<p class="md-end-block md-p"><span class="md-plain">乘法指令隐含使用一个操作数,它寄存在AX寄存器中。</span></p>
<p class="md-end-block md-p"><span class="md-plain">若字节量相乘,则结果传入AX中,而如果AX中高八位不为零,则OF=CF=1;若字量相乘,则高位传入DX,低位传入AX,若DX不为零,则OF=CF=1;</span></p>
<pre class="md-fences mock-cm md-end-block">mul/imul byte/word ptr mem/reg</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">除法指令DIV/IDIV</span></h2>
<p class="md-end-block md-p"><span class="md-plain">无符号数除法指令DIV,有符号数除法指令IDIV。</span></p>
<p class="md-end-block md-p"><span class="md-plain">除法指令隐含使用一个操作数(被除数),它寄存在AX中。</span></p>
<p class="md-end-block md-p"><span class="md-plain">先存商,在再存余数。如果除数是字节量,则商传入AL,余数传入AH;如果除数是字,则商传入AX,余数传入DX。</span></p>
<p class="md-end-block md-p"><span class="md-plain">如果除法产生溢出,被除数远大于除数或者除数为0,则发生除法溢出,引发编号为0的内部中断。</span></p>
<pre class="md-fences mock-cm md-end-block">div/idiv byte/word ptr mem/reg</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">符号扩展指令<span class="md-pair-s "><strong>CBW/CWD</strong></span></span></h2>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>CBW:</strong><span class="md-plain">将AL的最高有效位D<span class="md-pair-s"><span class="md-plain">7<span class="md-plain">拓展至AH,即假如AL的最高有效位(符号位)为0,则AH=00H;假如AL的最高有效位(符号位)为1,则AH=FFH。</span></span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>CWD:</strong><span class="md-plain">将AX的最高有效位D<span class="md-pair-s"><span class="md-plain">15<span class="md-plain">拓展至DX,即假如AX的最高有效位(符号位)为0,则DX=0000H;假如AX的最高有效位(符号位)为1,则DX=FFFFH。</span></span></span></span></span></p>
<pre class="md-fences mock-cm md-end-block">cbw<br>cwd</pre>
<p class="md-end-block md-p"><span class="md-plain">例如:有符号数AX/BX</span></p>
<pre class="md-fences mock-cm md-end-block">cwd<br>idiv bx</pre>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">十进制调整指令</span></h2>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>什么是压缩BCD码,什么是非压缩BCD码?</strong></span></p>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>压缩BCD码:</strong><span class="md-plain">用<span class="md-pair-s"><span class="md-plain">4个二进制位</span><span class="md-plain">表示一个十进制位,1个字节可以表示两个十进制位,即00-99。</span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>非压缩BCD码:</strong><span class="md-plain">用<span class="md-pair-s"><span class="md-plain">8个二进制位</span><span class="md-plain">表示一个十进制位,实际上只是用低四个二进制位表示一个十进制0-9,高四位任意,但通常默认为0。</span></span></span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-plain">非压缩BCD码也有对应的调整指令,但比较多,放弃了,不做记录。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>压缩BCD码调整指令</strong></span></p>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>DAA:</strong><span class="md-plain">跟在以AL为目的操作数的ADD或ADC指令后,对AL的二进制结果进行十进制调整。</span></span></p>
<p class="md-end-block md-p"><span class="md-pair-s "><strong>DAS:</strong><span class="md-plain">跟在以AL为目的操作数的SUB或SBB指令后,对AL的二进制结果进行十进制调整</span></span></p>
<pre class="md-fences mock-cm md-end-block">daa<br>das</pre>
<p class="md-end-block md-p"><span class="md-plain">例如:已知AX=1234H,BX=4612H,计算1234-4612的差</span></p>
<pre class="md-fences mock-cm md-end-block">sub al, bl<br>das<br>xchg al, ah<br>sbb al, bh<br>das<br>xchg al, ah</pre>
<div>&nbsp;</div>
<p class="md-end-block md-p">&nbsp;</p><br><br>
来源:https://www.cnblogs.com/LimeCoder/p/16834839.html
頁: [1]
查看完整版本: 汇编语言-8086指令(上)