汇编语言IMUL指令:有符号数乘法
x86 指令集支持三种格式的 IMUL 指令:单操作数、双操作数和三操作数。单操作数格式中,乘数和被乘数大小相同,而乘积的大小是它们的两倍。
单操作数格式
单操作数格式将乘积存放在 AX、DX:AX 或 EDX:EAX 中:
IMUL reg/mem8 ; AX = AL * reg/mem8
IMUL reg/meml6 ; DX:AX = AX * reg/meml6
IMUL reg/mem32 ; EDX:EAX = EAX * reg/mem32
双操作数格式(32位模式)
32 位模式中的双操作数 IMUL 指令把乘积存放在第一个操作数中,这个操作数必须是寄存器。第二个操作数(乘数)可以是寄存器、内存操作数和立 即数。16位格式如下所示:
IMUL regl6, reg/meml6
IMUL regl6, imm8
IMUL regl6, imml6
IMUL reg32, reg/mem32
IMUL reg32, inun8
IMUL reg32, imm32
三操作数格式
32 位模式下的三操作数格式将乘积保存在第一个操作数中。第二个操作数可以是 16 位寄存器或内存操作数,它与第三个操作数相乘,该操作数是一个8位或16 位立即数:
IMUL regl6, reg/meml6,imm8
IMUL regl6, reg/meml6, iirrnl6
IMUL reg32, reg/mem32, imm8
IMUL reg32, reg/mem32, imm32
在 64 位模式下执行 IMUL
在 64 位模式下,IMUL 指令可以使用 64 位操作数。在单操作数格式中,64 位寄存器或内存操作数与 RAX 相乘,产生一个 128 位且符号扩展的乘积存放到 RDX:RAX 寄存器中。在下面的例子中,RBX 与 RAX 相乘,产生 128 位的乘积 -16。
mov rax, -4
mov rbx, 4
imul rbx ; RDX = 0FFFFFFFFFFFFFFFFh, RAX = -16
三操作数格式也可以用于 64 位模式。如下例所示,被乘数 (-16) 乘以 4,生成 RAX 中的乘积 -64:
.data multiplicand QWORD -16 .code imul rax, multiplicand, 4 ; RAX = FFFFFFFFFFFFFFC0 (-64)
无符号乘法
由于有符号数和无符号数乘积的低半部分是相同的,因此双操作数和三操作数的 IMUL 指令也可以用于无符号乘法。但是这种做法也有一点不便的地方:进位标志位和溢出标志位将无法表示乘积的高半部分是否为零。IMUL 示例
下述指令执行 48 乘以 4,乘积 +192 保存在 AX 中。虽然乘积是正确的,但是 AH 不是 AL 的符号扩展,因此溢出标志位置 1:
mov al,48
mov bl, 4
imul bl ; AX = 00C0h, OF = 1
mov al, -4
mov bl, 4
imul bl ; AX = FFF0h, OF = 0
mov ax, 48
mov bx, 4
imul bx ; DX:AX = 000000C0h, OF = 0
mov eax, +4823424
mov ebx, -423
imul ebx ; EDX:EAX = FFFFFFFF86635D80h, OF = 0
.data word1 SWORD 4 dword1 SDWORD 4 .code mov ax, -16 ; AX = -16 mov bx, 2 ; BX = 2 imul bx, ax ; BX = -32 imul bx, 2 ; BX = -64 imul bx, word1 ; BX = -256 mov eax, -16 ; EAX = -16 mov ebx, 2 ; EBX = 2 imul ebx, eax ; EBX = -32 imul ebx, 2 ; EBX = -64 imul ebx, dword1 ; EBX = -256双操作数和三操作数 IMUL 指令的目的操作数大小与乘数大小相同。因此,有可能发生有符号溢出。执行这些类型的 IMUL 指令后,总要检查溢岀标志位。下面的双操作数指令展示了有符号溢出,因为 -64000 不适合 16 位目的操作数:
mov ax, -32000
imul ax, 2 ; OF = 1
.data word1 SWORD 4 dword1 SDWORD 4 .code imul bx, word1, -16 ; BX = word1 * -16 imul ebx, dword1, -16 ; EBX = dword1 * -16 imul ebx, dword1, -2000000000 ; 有符号溢出!