MUL 是无符号乘法指令。 MUL(无符号乘法)指令有三种格式:第一种是将8位操作数乘以al。第二种是将16位操作数与ax相乘;第三种是将32位操作数与eax相乘
乘数和被乘数的大小必须相同,并且乘积的大小是乘数/被乘数大小的两倍。所有三种格式都接受寄存器和内存操作数。但它不接受立即操作数(请注意这一点)。
例如:
如果要将al寄存器中的值乘以2,那么需要将立即数2存入寄存器,然后通过mul指令相乘,或者将立即数放入内存地址,然后使用内存单元的乘法形式。
示例:
移动, 2
穆尔BL;此时将bl寄存器中的值乘以al寄存器中的值
指令中唯一的操作数是乘法器。
也就是说,当我们的乘法器是8位时,它乘以al,如果我们的乘法器是16位,它乘以ax,如果我们的乘法器是32位,它乘以eax寄存器。
那么下面我给出乘法相关操作数的例子
被乘数乘积
al 8 位操作数ax
ax 16 位操作数dx:ax
eax 32 位操作数edx:eax
因为如果我们的乘法器是一个8 位操作数,那么我们的结果存在于ax 寄存器中。如果是16位操作数,我们的结果存储在dx:ax中。如果dx 不为0,则设置进位标志。
执行完mul指令后,我们一般会检查进位标志。因为我们需要知道是否可以安全地忽略乘积的高半部分。
例如:
移动6 小时
移动,10小时
穆尔布尔
此时我们检查进位标志cf=0,那么ah我们可以忽略它,所以结果是60h。
我们再举一个例子:
例如:
移动斧头,6000
移动bx,5000
xx
我们检查进位标志,此时cf=1。然后我们的结果是dx:ax。这时候我们的dx=1E00,ax=0000,所以我们最终的结果就是1E000000。
其实我们可以从乘积算出cf是否被设置。
1.接下来我们留个小作业,不使用其他辅助工具来计算。自己计算一下,执行后的产品是什么?
移动eax,00800000
移动ebx,00200000
穆莱克斯
编译基础一日学习31 IMUL
大家好,今天我们来学习有符号整数的乘法运算,IMUL指令。该指令保留乘积的符号位。 IMUL指令,IA-32指令集中有三种格式:单操作数、双操作数和三操作数。在单操作数格式中,乘数和被乘数的大小相同,并且乘积的大小是乘数/被乘数大小的两倍。
单操作数格式: 单操作数格式将乘积存储在累加器中(ax、dx:ax、edx:eax)。 imul指令的单操作数格式其实和我们昨天学习的mul指令格式基本相同。
1、然后我们看一下IMUL单操作数:的格式
imul 8 位寄存器/8 位内存操作数
imul 16 位寄存器/16 位内存操作数
imul 32 位寄存器/32 位内存操作数
2.双操作数数字格式:
imul 16位寄存器/16位寄存器-16位内存操作数
imul 16 位寄存器/8 位立即数
imul 16位寄存器/16位立即数
从上面我们可以看出,在双操作数格式中,乘积存储在第一个操作数中,第一个操作数必须是寄存器,第二个操作数可以是寄存器、内存操作数或立即数。我在上面给了你一些基于16 位的双操作数的例子。当然也可以是32位的。
imul 32位寄存器/32位寄存器-32位内存操作数
imul 32 位寄存器/8 位立即数
imul 32 位寄存器/32 位立即值
3. 三操作数格式:
imul 16位寄存器/16位寄存器-16位内存操作数/8位立即数
imul 16位寄存器/16位寄存器-16位内存操作数/16位立即数
三操作数格式将乘积存储在第一个操作数中。 16 位寄存器可以乘以8 位或16 位立即数。
imul 32 位寄存器/32 位寄存器- 32 位内存操作数/8 位立即数
imul 32 位寄存器/32 位寄存器- 32 位内存操作数/32 位立即数
如果有效位丢失,则溢出标志和进位标志被置位。使用三操作数格式时,请务必在执行imul运算后检查相关操作位。
好吧,我猜你光看理论就感到困惑了,所以让我们看几个例子:
1. 例如mov al, -3
移动, 6
伊穆布尔
此时执行时,(-3*6)的结果存放在ax寄存器中。正如我上面所说,执行imul进行有符号整数的乘法时,会保留乘积的符号位,也就是说保留乘积的高半部分。部分是下半部分的标志延伸。符号扩展是什么意思?也就是说,如果我们的乘积是负数,则高半部分为1,如果乘积是正数,则高半部分为0。显然我们的(-3*6)是负数,所以较高的此时half必须为1。如果你不相信我,请计算一下。
-3的十六进制表示为0FDh
幸运的是,现在我们将0FD 转换为二进制补码形式。你还记得将十六进制整数转换为二进制补码的方法吗? 15减去每一位十六进制数字,最后的结果是+1。
现在
f
15 – F=0
15 – D=2
+ 1=03小时
03*6h=12h(注意十进制的18=十六进制的12h)
此时我们将对12h 进行补码,这将是我们的最终产品
12小时
15 – 1=E
15 – 2=D
+ 1=EEh
由于EEh的最高符号位为1,所以高半部分将扩展到低半部分的符号位,因此高半部分为FF(即所有二进制位均为1)。
最终结果是FFEEh。由于已经展开了,此时of=0。 (也就是说,如果没有展开的话,of=1)。
2.我们再看一个例子
移动3 小时
移动,6小时
伊穆布尔
大家可以口头算一下。显然3*6=18,十六进制=12h。此时,结果为正,因为结果是12h,但我们不能使用of或if来表示乘积的高半部分。该部分是否为0,也就是说,我们的imul虽然可以进行无符号整数运算,但是我们无法通过它影响的标志位来判断。
3.我们再看一个例子
莫夫阿尔,48
移动, 3
伊穆布尔
显然我们的结果是一个正数,结果的乘积+144存储在ax中。由于ah 不是al 的符号扩展,因此设置溢出标志。=1的
4.那么我再举一个有2个操作数的例子。
移动斧头,-30h
移动bx,10小时
伊穆尔斧头,bx
那么-30 * 10=-48 * 16=-768
=-300小时
然后我们找到补码
300
15 – 3=C
15 – 0=F
15 – 0=F
+ 1=D00
因为我们的结果是负数,因为我们的结果保存在ax寄存器中,又因为上面说了有符号值的乘积是有符号位扩展的,所以高4位应该全部补1,所以最终结果是FD00h
5. 接下来我们有一个3 位操作数。
移动斧头,-30h
imul bx, 斧头, 2h
这三个操作数的目的是将结果存储在第一个操作数中。
-30 * 2=-60
此时取补码
15 – 6=9
15 – 0=F
+1=A0
产品=FFA0h,存储在bx 中。
离职:
1.
移动斧头,-60h
伊穆尔bx, 斧头, 3
:是什么产品?
编译基础知识,一日学习32 DIV
大家好,今天我们来学习无符号整数的除法运算指令。 p(无符号)指令执行8 位、16 位和32 位无符号整数的除法运算。指令中唯一的寄存器或内存操作数必须是除数。
p 命令格式:
p 8位寄存器/8位内存操作数
p 16位寄存器/16位内存操作数
p 32位寄存器/32位内存操作数
p指令格式基本上与我们的mul相反。接下来我们看看被除数、除数、商、余数之间的关系。
被除数商余数
ax 8位寄存器/8位内存操作数al ah
dx:ax 16位寄存器/16位内存操作数ax dx
edx:eax 32 位寄存器/32 位内存操作数eax edx
1.
例如:
移动斧头,0060h
移动, 2
p bl ;al=30h , ah=00h
那么执行后商为30h余数为00h
2.
举个例子
执行(6005h/100h),由于我们的输出是16位,所以被除数放在dx:ax中。但由于被除数是6005h,所以我们必须将dx清0。
异或dx, dx
莫夫斧头,6005h
移动bx,100小时
像素
那么执行后我们的ax=0060h,dx=0005h。所以我们的商是60h,余数是5h。
很简单。