当前位置: 首页 > news >正文

x86汇编_MUL/IMUL乘法指令_笔记52

32位模式下整数乘法可以实现32、16或8位的操作,64位下还可以使用64位操作数。MUL执行无符号乘法,IMUL执行有符号乘法。

MUL指令:无符号数乘法

32 位模式下,MUL(无符号数乘法)指令有三种类型:

  • 执行 8 位操作数与 AL 寄存器的乘法;
  • 执行 16 位操作数与 AX 寄存器的乘法;
  • 执行 32 位操作数与 EAX 寄存器的乘法。

MUL 指令中的单操作数是乘数。下表按照乘数的大小,列出了默认的被乘数和乘积。由于目的操作数是被乘数和乘数大小的两倍,因此不会发生溢岀,换句话说,两个8位二进制数的乘积不会超过16位

MUL无符号指令
被乘数乘数乘积存放位置备注
ALreg8/mem8AXMUL操作数是8位寄存器,自动将AL当作被乘数。结果存放AX。
AXreg16/mem16DX:AXMUL操作数是16位寄存器,自动将AX当作被乘数。结果的低位放在AX,高位在DX。
EAXreg16/mem32EDX:EAXMUL操作数是32位寄存器,自动将EAX当作被乘数。结果的低位在EAX,高位在EDX。

如果乘积的高半部分不为零,则 MUL 会把进位标志位和溢出标志位置 1。因为进位标志位常常用于无符号数的算术运算,在此我们也主要说明这种情况。例如,当 AX 乘以一个 16 位操作数时,乘积存放在 DX 和 AX 寄存器对中。其中,乘积的高 16 位存放在 DX,低 16 位存放在 AX。如果 DX 不等于零,则进位标志位置 1,这就意味着目的操作数的低半部分放不了整个乘积。

下述语句实现 16 位值 2000h 乘以 0100h。由于乘积的高半部分(存放于 DX)不等于零,因此进位标志位被置 1。注意,CF是1仅代表DX寄存器不为0,不是说DX和AX两个寄存不够存放结果

.data
val1 WORD 2000h
val2 WORD 0l00h

.code
mov ax, val1           ; AX = 2000h
mul val2               ; DX:AX = 00200000h, CF = 1

IMUL指令:有符号数乘法

与 MUL 指令不同,IMUL 会保留乘积的符号,但两个有符号8位数的乘积仍然不超过16位,不会因为有符号问题就超过16位。x86 指令集支持三种格式的 IMUL 指令:单操作数、双操作数和三操作数,而无符号的MUL指令只有单操作数。

对于单操作数的IMUL指令,规则同无符号的MUL。和 MUL 指令一样,其乘积的存储大小使得溢出不会发生。同时,如果乘积的高半部分不是其低半部分的符号扩展,则进位标志位和溢出标志位置 1。利用这个特点可以决定是否忽略乘积的高半部分。

IMUL有符号指令单操作数的规则
被乘数乘数乘积存放位置
ALreg/mem8AX
AXreg/mem16DX:AX
EAXreg/mem32EDX:EAX

 对于双操作数的IMUL指令,用第一个操作数乘以第二个操作,将结果存放到第一个操作所在的寄存器。第一操作数必须是16或32位寄存器,第二操作可以是16或32位内存或寄存器,位数与第一操作数对应。第二操作数还可以是8位立即数且只能是8位的。双操作数格式会按照目的操作数的大小来截取乘积,乘积的高半部分会被丢弃。如果被丢弃的是有效位,则溢出标志位和进位标志位置 1。因此,在执行了有两个操作数的 IMUL 操作后,必须检查这些标志位中的一个。

下述指令展示了双操作数格式:

.data
word1 SWORD 4     ;16位内存
dword1 SDWORD 4   ;32位内存
.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指令,第二和三个操作数的乘积存放到第一操作数中,第三操作数必须是立即数。若乘积有效位被丢弃,则溢出标志位和进位标志位置 1。因此,在执行了有三个操作数的 IMUL 操作后,必须检查这些标志位中的一个。格式如下:

imul 16位寄存器,16位寄存器或者内存,8或16位立即数

imul 32位寄存器,32位寄存器或者内存,8或32位立即数

下面的指令展示的是三操作数格式,包括了有符号溢出的例子:

.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   ; 有符号溢出!此时需要40个位才足够存放结果,而ebx只有32位。

相关文章:

  • CSP-J1 CSP-S1第1轮 初赛 如何拿到好成绩(60分及以上)
  • Package | 解决Could NOT find GLEW (missing: GLEW_INCLUDE_DIRS GLEW_LIBRARIES)
  • Maven的配置与安装
  • 阿里云 OSS
  • MacOS 12 Monterey根目录无法创建目录
  • 【牛客网-公司真题-前端入门篇】——百度2021校招Web前端研发工程师笔试卷(第一批)
  • 【Android控件】HorizontalScrollView的基础使用记录(滚动条自定义)
  • 盘点下常用的接口测试工具,有几个你肯定没用过
  • 成都市级科技计划项目验收公告、专精特新“小巨人”奖励申报等
  • 磁珠法RNA pull down试剂盒、蛋白质-核酸相互作用
  • GC 垃圾回收机制
  • C语言排序代码汇总测试
  • 力扣第五十六题(合并区间)详解
  • 【毕业设计】LSTM天气预测系统(时间序列预测)
  • Python毕业设计源代码员工人事系统
  • @angular/forms 源码解析之双向绑定
  • [Vue CLI 3] 配置解析之 css.extract
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • ComponentOne 2017 V2版本正式发布
  • egg(89)--egg之redis的发布和订阅
  • express + mock 让前后台并行开发
  • HTTP--网络协议分层,http历史(二)
  • JavaScript 基本功--面试宝典
  • JavaScript对象详解
  • JAVA之继承和多态
  • JS学习笔记——闭包
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • node入门
  • Spring Cloud Feign的两种使用姿势
  • Vue.js-Day01
  • 初识 beanstalkd
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 写代码的正确姿势
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • ###C语言程序设计-----C语言学习(3)#
  • #DBA杂记1
  • #微信小程序:微信小程序常见的配置传值
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (SpringBoot)第二章:Spring创建和使用
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .Net 6.0 处理跨域的方式
  • .NET Core引入性能分析引导优化
  • .NET delegate 委托 、 Event 事件
  • .Net 高效开发之不可错过的实用工具
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .net 使用ajax控件后如何调用前端脚本
  • .NET中使用Protobuffer 实现序列化和反序列化
  • .sdf和.msp文件读取