MUL是进行无符号乘法的指令。MUL(无符号乘法)指令有三种格式:第一种是将8位的操作数于al相乘。第二种是将16位的操作数与ax相乘;第三种是将32位的操作数与eax进行相乘
乘数和被乘数大小必须相同,乘积的尺寸是乘数/被乘数大小的两倍。三种格式都既接受寄存器操作数,也接受内存操作数。但是不接受立即操作数(这点大家注意下)。
例如:
你想将al寄存器中的值乘上2,那么此时你需要将立即数2存放到一个寄存器中,然后通过mul指令相乘,或者将立即数放到一个内存地址中,然后通过内存单元的形式来进行相乘。
举例:
movbl,2
mulbl;此刻将bl寄存器中的值乘上al寄存器中的值
指令中唯一的一个操作数是乘数。
也就是当我们的乘数是8位的时候,则与al相乘,如果我们的乘数是16位则与ax相乘,如果我们的乘数是32位则与eax寄存器相乘。
那么下面我给出mul乘法的相关操作数的实例
被乘数乘数积
al8位操作数ax
ax16位操作数dx:ax
eax32位操作数edx:eax
因为如果我们的乘数是一个8位操作数的话,我们的结果存在在ax寄存器中。如果是16位操作数的话,我们的结果存放在dx:ax中。如果dx不为0,则进位标志置位。
在执行完mul指令后,我们一般要检查下进位标志。因为我们需要知道乘积的高半部分是否可以安全的忽略。
例如:
moval,6h
movbl,10h
mulbl
此刻我们检查进位标志cf=0,那么ah我们就可以将其忽略了,所以结果是60h。
那么我们再来举一个例子:
例如:
movax,6000
movbx,5000
mulbx
我们检查进位标志,此时cf=1。那么我们的结果是dx:ax,此时我们的dx=1E00,ax=0000所以最后我们的积为1E000000。
其实我们从乘积就可以算出来cf是否置位了。
1.接下来我们留个小作业,不要用其他辅助工具来计算。自己口算下,执行完后,积为多少?
moveax,00800000
movebx,00200000
mulebx
汇编基础一日一学习31IMUL
大家好,今天我们来学习下有符号整数的乘法运算,IMUL指令。这个指令保留了乘积的符号位。IMUL指令,IA-32指令集中有三种格式:单操作数、双操作数和三操作数。在单操作数格式中,乘数和被乘数尺寸大小相同,乘积的大小是乘数/被乘数大小的两倍。
单操作数格式:单操作数格式把乘积存储在累加器(ax,dx:ax,edx:eax)中。imul指令单操作数格式其实和我们昨天学习的mul指令格式基本一样。
1.那么接下来我们来看下IMUL单操作数的格式:
imul8位寄存器/8位内存操作数
imul16位寄存器/16位内存操作数
imul32位寄存器/32位内存操作数
2.双操作数数格式:
imul16位寄存器/16位寄存器-16位内存操作数
imul16位寄存器/8位立即数
imul16位寄存器/16位立即数
从上面我们可以看出双操作数格式中,乘积存储在第一个操作数中,第一个操作数必须是寄存器,第二个操作数可以是寄存器、内存操作数、或立即数。上面双操作数我是按照16位来给大家举的一些例子。它当然还可以是32位的。
imul32位寄存器/32位寄存器-32位内存操作数
imul32位寄存器/8位立即数
imul32位寄存器/32位立即数
3.三操作数格式:
imul16位寄存器/16位寄存器-16位内存操作数/8位立即数
imul16位寄存器/16位寄存器-16位内存操作数/16位立即数
三操作数格式把乘积存储在第一个操作数,一个16位寄存器可以被一个8位或者16位的立即数乘。
imul32位寄存器/32位寄存器-32位内存操作数/8位立即数
imul32位寄存器/32位寄存器-32位内存操作数/32位立即数
如果有效位丢失,则溢出标志和进位标志置位。使用三操作数格式时,一定要在执行完imul操作后检查相关操作位。
好,光看理论估计你很迷糊,那么我们就来看几个实例:
1.例如moval,-3
movbl,6
imulbl
此刻执行的时候(-3*6)的结果存放到ax寄存器中,由于上面我说了,在执行imul进行有符号整数的乘法运算时,保留了乘积的符号位,也就是说乘积的高半部分是低半部分的符号扩展。符号扩展是什么意思呢?也就是说如果我们的乘积是个负数则,高半部分都为1,如果乘积是个正数的话,高半部分都为0。很显然我们(-3*6)是负数,所以此时高半部分肯定是1,不信大家来计算下。
-3的16进制表示形式是0FDh
好此刻我们将0FD转换成补码的形式,大家不知道还记得16进制整数转换补码的方法吗,用15减去各个进制位,最终结果+1。
此刻
FDh
15-F=0
15-D=2
+1=03h
03*6h=12h(注意10进制18=16进制12h)
此刻我们将取12h的补码则为我们最后的乘积
12h
15-1=E
15-2=D
+1=EEh
由于EEh的最高符号位是1,所以此时高半部分将扩展为低半部分的符号位,所以此时高半部分为FF(也就是全是二进制位1)。
最终的结果是FFEEh,此时由于已经被扩展了,所以此时的of=0。(也就是说如果没有扩展的话,of=1)。
2.再来看个例子
moval,3h
movbl,6h
imulbl
大家口算就可以算的出来,很显然3*6=18,16进制=12h,此时由于结果为正,因为结果是12h,但是我们也并不能通过of或者是if来指示乘积的高半部分是否为0,也就是说我们的imul虽然能进行无符号整数运算,但是我们不能通过它影响的标志位来进行判断。。
3.再来看个例子
moval,48
movbl,3
imulbl
很显然我们的结果为正数,得到的积+144存放在ax中,由于ah不是al的符号扩展,因为溢出标志位置位。of=1
4.那么接下来我再来举个2操作数的。
movax,-30h
movbx,10h
imulax,bx
那么-30*10=-48*16=-768
=-300h
然后我们求反码
300
15-3=C
15-0=F
15-0=F
+1=D00
因为我们的结果是负数,因为我们的结果是存在ax寄存器中的,而由于上面说了有符号数值的乘积是带符号位扩展的,高4位应该全是1填充,所以最终结果为FD00h
5.接下来我们来个3位操作数的。
movax,-30h
imulbx,ax,2h
这三个操作数的是将结果存放在第一个操作数中。
-30*2=-60
这时候取反码
15-6=9
15-0=F
+1=A0
乘积=FFA0h,存放到bx中。
留个作业:
1.
movax,-60h
imulbx,ax,3
问:乘积多少?
汇编基础一日一学习32DIV
大家好,今天我们来学习下无符号整数的除法运算指令,div(无符号)指令执行8位、16位和32位无符号整数的除法运算。指令中必须是唯一的一个寄存器或内存操作数是除数。
div指令格式:
div8位寄存器/8位内存操作数
div16位寄存器/16位内存操作数
div32位寄存器/32位内存操作数
div指令格式和我们的mul基本可以算作是相反的。那么我们看下被除数、除数、商、余数之间的关系。
被除数除数商余数
ax8位寄存器/8位内存操作数alah
dx:ax16位寄存器/16位内存操作数axdx
edx:eax32位寄存器/32位内存操作数eaxedx
1.
举个例子:
movax,0060h
movbl,2
divbl;al=30h,ah=00h
那么执行完后,商是30h,余数是00h
2.
在举个例子
执行(6005h/100h),由于我们的出示是16位,所以被除数是放在dx:ax中的。但是由于被除数是6005h,所以我们必须将dx清0.
xordx,dx
movax,6005h
movbx,100h
divbx
那么执行后,我们的ax=0060h,dx=0005h。所以我们的商是60h,余数是5h。
很简单。





