汇编语言乘法和除法指令


乘法和除法指令
IA-32 处理器的乘法和除法指令需要区别无符号数和有符号数, 并隐含便用丁 EAX (和EDX) 寄存器。

1.乘法指令MUL/IMUL

基本的乘法指令指出源操作数 reg/mem (寄存器或存储单元), 隐含使用目的操作数,表3。若源操作数是8位数8/m8,AL与其相乘得到16位积,存入AX中,若源操作数是 16 位数 r16/m16, AX 与其相乘得到 32 位积, 高 16 位存人 DX, 低 16 位存入AX中; 若源操作数是32位数r32/m32,EAX与其相乘得到64位积,高32位存人EDX,低32位存人EAX中。
表1
在这里插入图片描述
乘法 (multiplication) 指令分成无符号数乘法指令 MUL和有符号数乘法指令 IMUL。 同一个二进制编码表示无符号数和有符号数时, 真值可能不同。

例如,用MUL进行8位无符号乘法运算:
mov al,0a5h;ALA5H,作为无符号整数编码,表示真值:165
mov bl,64h;BL=64H,作为无符号整数编码,表示真值:100
mul bl;无符号乘法:AX=4074H,表示真值:16500

再如, 用IMUL进行8位有符号乘法运算:
mov al,0a5h;AL=A5H,作为有符号整数补码,表示真值:-91
mov bl,64h;BL=64H,作为有符号整数补码,表示真值:100
imul bl;有符号乘法:AX=DC74H,表示真值:-9100
所以, 对二进制数乘法: A5H x64H, 如果把它们当作无符号数, 用 MUL指令的结果为4074H, 表示真值:16500。 如果采用IMUL指令, 则结果为DC74H, 表示真值: -9100。
注意 加减指令只进行无符号数运算,程序员利用CF和OF区别结果
基本的乘法指令按如下规则影响标志OF和CF: 若乘积的高一半是低一半的符号位扩展, 说明高一半不含有效数值, 则OF=CF=0; 若乘积的高一半有效, 则用OF=CF=1 表示。 设置OF和CF标志的原因, 是有时我们需要知道高一半是否可以被忽略, 即不影响结果。
但是, 乘法指令对其他状态标志没有定义, 即任意、 不可预测。 注意, 这一点与数据传送类指令对标志没有影响是不同的, 没有影响是指不改变原来的状态。
从80186开始, 有符号数乘法又提供了两种新形式, 如表1后两行所示。 这些新增的乘法形式的目的操作数和源操作数的长度相同 (用于支持高级语言中类型一致的乘法运算), 因此乘积有可能溢出。 如果积溢出, 那么高位部分被丢掉, 并设置CF=OF=1; 如果没有溢出, 则CF-OF=0。 后一种形式采用了3个操作数, 其中一个乘数用立即数表达。
由于存放积的目的操作数长度与乘数的长度相同, 而有符号数和无符号数的乘积的低位部
分是相同的, 所以 , 这种新形式的乘法指令对有符号数和无符号数的处理是相同的。

2.除法指令DIV/IDIV

除法指令给出源操作数 reg/mem (寄存器或存储单元), 隐含使用目的操作数, 如表2
所示。
在这里插入图片描述
与乘法指令类似, 除法 (division) 指令也隐含使用 EAX (和 EDX), 并且被除数的位数要
倍长于除数的位数。 除法指令也分成无符号除法指令 DIV 和有符号除法指令IDIV。 有符号除法时, 余数的符号与被除数的符号相同。 对同一个二进制编码, 分别采用 DIV 和 IDIV 指令后, 商和余数也会不同。

例如,用DIV进行8位无符号除法运算:
mov ax,400h;AX=400H,作为无符号整数编码,表示真值:1024 X2M0
mov bl,0b4h:BL=B4H,作为无符号整数编码,表示真值:180
div bl:无符号除法:商AL=05H,余数:AH=7CH(真值:124)
;表示计算结果:5x180+124=1024

再如, 用IDIV 进行8位有符号除法运算:
mov ax,400h;AX=400H,作为有符号整数补码,表示真值:1024
mov bl,0b4h;BL=B4H,作为有符号整数补码,表示真值:-76
idiv bl;有符号除法:商AL=F3H(真值:-13),余数:AH=24H(真值:36)
;表示计算结果:(-13)x(-76)+36=1024
除法指令使状态标志没有定义, 但是却可能产生除法溢出。 除数为0或者商超出了所能表达的范围, 则发生除法溢出。 用DIV指令进行无符号数除法, 商所能表达的范围是: 字节量除时为0-255,字量除时为0~65535,双字量除时为0-232-1。用IDIV指令进行有符号数除法,
商所能表达的范围是:字节量除时为-128127,字量除时为-3276832767,双字量除时
为-231~232 -1。 如果发生除法溢出,IA-32处理器将产生编号为0的内部中断。实际应用中应该考虑这个问题, 操作系统通常只会提示错误。

3.其他运算指令

除基本的二进制加减乘除指令外,算术运算指令还包括十进制 BCD码运算以及与运算相关的符号扩展等指令。

  1. 零位扩展和符号扩展指令
    IA-32处理器支持8,16和32位数据操作,大多数指令要求两个操作数类型一致。但是,实际的数据类型不一定满足要求。例如,32位与16位数据的加减运算,需要先将16位扩展为32位。 再如,32位除法需要将被除数扩展成64位。 不过, 位数扩展后数据大小不能因此改变。
    对无符号数据,只要在前面加0就实现了位数扩展、大小不变,这就是零位扩展(zeroextension), 对应指令 MOVZX, 如表3, 例如, 8位无符号敷据80H (128) 零位扩展为位0080H(-128).
    在这里插入图片描述
    MOVZX指令下
    nov al.82h;AL=82H
    movzx bx,al;AL=82H,零位扩展:BX=0082H
    movzx ebx,a1:AL=82H,零位扩展:EBX=00000082H
    对有符号数据, 需要进行符号扩展 (sign extension), 即用一个操作数的符号位 (最高位)形成另一个操作数, 对应指令MOVSX. 例如, 8位有符号数据64H(100) 为正数, 符号位为O, 符号扩展成16位是0064H(100)。 再如,16位有符号数据 FFOOH( -256) 为负数, 符号位为1, 符号扩展成32位是FFFFFFOOH (- -256). 特别典型的例子是真值-1, 字节量补码表达是FFH, 字量补码表达是FFFFH,双字量补码表达是FFFFFFFFH.
    MOVSX指令举例如下:
    mov al,82h;AL=82H
    movsx bx,al;AL=82H,符号扩展:BX=FF82H
    movsx ebx,al;AL=82H,符号扩展:EBX=FFFFFF82H
    零位扩展对应无符号数, 符号扩展对应有符号数, 它们使数据位数加长, 但数据大小井设有改变。 另外, 还可以使用符号扩展指令CBW、 CWD, CWDE 和CDQ, 它们的功能分别是将AL符号扩展为AX、 AX符号扩展为DX和AX、 AX符号扩展为EAX、 EAX符号扩展为EDX和 EAX。 Intel 8086 只支持 CBW 和 CWD 指令, 不支持包括 MOVZX 和 MOVSX 在内的其他扩展。
  • 16
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值