鑫洲驾校龚贵乔 發表於 2021-2-4 10:34:03

汇编语言MUL指令无符号数乘法的使用

<p>32 位模式下,MUL(无符号数乘法)指令有三种类型:</p>
<ul>
<li>第一种执行 8 位操作数与 AL 寄存器的乘法;</li>
<li>第二种执行 16 位操作数与 AX 寄存器的乘法;</li>
<li>第三种执行 32 位操作数与 EAX 寄存器的乘法。</li>
</ul>
<p>乘数和被乘数的大小必须保持一致,乘积的大小则是它们的一倍。这三种类型都可以使用寄存器和内存操作数,但不能使用立即数:<br />
</p>
<div class="jb51code">
<pre class="brush:plain;">
MUL reg/mem8
MUL reg/meml6
MUL reg/mem32
</pre>
</div>
<p>MUL 指令中的单操作数是乘数。下表按照乘数的大小,列出了默认的被乘数和乘积。由于目的操作数是被乘数和乘数大小的两倍,因此不会发生溢岀。<br class="Apple-interchange-newline" />
</p>
<p>
<table>
<tbody>
    <tr>
      <th>被乘数</th>
      <th>乘数</th>
      <th>乘积</th>
    </tr>
    <tr>
      <td>AL</td>
      <td>reg/mem8</td>
      <td>AX</td>
    </tr>
    <tr>
      <td>AX</td>
      <td>reg/mem16</td>
      <td>DX:AX</td>
    </tr>
    <tr>
      <td>EAX</td>
      <td>reg/mem32</td>
      <td>EDX:EAX</td>
    </tr>
</tbody>
</table>
</p>
<p>如果乘积的高半部分不为零,则 MUL 会把进位标志位和溢出标志位置 1。因为进位标志位常常用于无符号数的算术运算,在此我们也主要说明这种情况。例如,当 AX 乘以一个 16 位操作数时,乘积存放在 DX 和 AX 寄存器对中。其中,乘积的高 16 位存放在 DX,低 16 位存放在 AX。如果 DX 不等于零,则进位标志位置 1,这就意味着隐含的目的操作数的低半部分容纳不了整个乘积。</p>
<p>有个很好的理由要求在执行 MUL 后检查进位标志位,即,确认忽略乘积的高半部分是否安全。<br />
</p>
<h3>MUL 示例<br />
</h3>
<p>下述语句实现 AL 乘以 BL,乘积存放在 AX 中。由于 AH(乘积的高半部分)等于零,因此进位标志位被清除(CF=0):<br />
</p>
<div class="jb51code">
<pre class="brush:plain;">
mov al, 5h
mov bl, 10h
mul bl          ; AX = 0050h, CF = 0
</pre>
</div>
<p>下图展示了寄存器内容的变化:</p>
<p style="text-align: center"><img src="https://img.jbzj.com/file_images/article/202102/202124103207519.gif?202114103220" alt="" /></p>
<p>下述语句实现 16 位值 2000h 乘以 0100h。由于乘积的高半部分(存放于 DX)不等于零,因此进位标志位被置 1:<br />
</p>
<div class="jb51code">
<pre class="brush:plain;">
.data
val1 WORD 2000h
val2 WORD 0l00h
.code
mov ax, val1      ; AX = 2000h
mul val2      ; DX:AX = 00200000h, CF = 1
</pre>
</div>
<p style="text-align: center"><img src="https://img.jbzj.com/file_images/article/202102/202124103236918.gif?202114103246" alt="" /></p>
<p>下述语句实现 12345h 乘以 1000h,产生的 64 位乘积存放在 EDX 和 EAX 寄存器对中。EDX 中存放的乘积高半部分为零,因此进位标志位被清除:<br />
</p>
<div class="jb51code">
<pre class="brush:plain;">
mov eax, 12345h
mov ebx, 1000h
mul ebx          ; EDX:EAX = 0000000012345000h, CF = 0
</pre>
</div>
<p>下图展示了寄存器内容的变化:</p>
<p style="text-align: center"><img src="https://img.jbzj.com/file_images/article/202102/202124103316506.gif?202114103326" alt="" /></p>
<h3>在 64 位模式下使用 MUL<br />
</h3>
<p>64 位模式下,MUL 指令可以使用 64 位操作数。一个 64 位寄存器或内存操作数与 RAX 相乘,产生的 128 位乘积存放到 RDX:RAX 寄存器中。下例中,RAX 乘以 2,就是将 RAX 中的每一位都左移一位。RAX 的最高位溢出到 RDX 寄存器,使得 RDX 的值为 0000 0000 0000 0001h:<br />
</p>
<div class="jb51code">
<pre class="brush:plain;">
mov rax, 0FFFF0000FFFF0000h
mov rbx, 2
mul rbx         ; RDX:RAX = 0000000000000001FFFE0001FFFE0000
</pre>
</div>
<p>下面的例子中,RAX 乘以一个 64 位内存操作数。该寄存器的值乘以 16,因此,其中的每个十六进制数字都左移一位(一次移动 4 个二进制位就相当于乘以 16)。<br />
</p>
<div class="jb51code">
<pre class="brush:plain;">
.data
multiplier QWORD 10h
.code
mov rax, OAABBBBCCCCDDDDh
mul multiplier    ; RDX:RAX = 00000000000000000AABBBBCCCCDDDDOh
</pre>
</div>
<p>到此这篇关于汇编语言MUL指令无符号数乘法的使用的文章就介绍到这了,更多相关汇编语言MUL指令内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!&nbsp;</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>汇编语言功能用循环累加实现乘法</li><li>一位数乘法的汇编语言实现方法</li><li>汇编高效乘法运算的具体使用方法</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: 汇编语言MUL指令无符号数乘法的使用