汇编语言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 ; 有符号溢出!
所有教程
- socket
- Python基础教程
- C#教程
- MySQL函数
- MySQL
- C语言入门
- C语言专题
- C语言编译器
- C语言编程实例
- GCC编译器
- 数据结构
- C语言项目案例
- C++教程
- OpenCV
- Qt教程
- Unity 3D教程
- UE4
- STL
- Redis
- Android教程
- JavaScript
- PHP
- Mybatis
- Spring Cloud
- Maven
- vi命令
- Spring Boot
- Spring MVC
- Hibernate
- Linux
- Linux命令
- Shell脚本
- Java教程
- 设计模式
- Spring
- Servlet
- Struts2
- Java Swing
- JSP教程
- CSS教程
- TensorFlow
- 区块链
- Go语言教程
- Docker
- 编程笔记
- 资源下载
- 关于我们
- 汇编语言
- 大数据
- 云计算
- VIP视频