X86汇编MUL、IMUL、DIV、IDIV、CBW、CWD、CDQ指令简介

MUL指令无符号数乘法

  • 指令有三种类型,第一种类型是执行8位立即数和AL寄存器的乘法,第二种类型是执行16位数和AX寄存器的乘法,第三种是执行32位数和EAX寄存器的乘法。

  • 语法如下

    1. mul reg/mem8
    2. mul reg/mem16
    3. mul reg/mem32
  • mul乘法,被乘数、乘数、乘积的表格如下

    被乘数乘数乘积
    ALreg/mem8AX
    AXreg/mem16DX:AX
    EAXreg/mem32EDX:EAX
  • 乘积的高半部分不为0,则MUL会把进位标志和溢出标志置为1

  • 示例代码如下

    1. ; vs2022 MASM环境代码示例
      .386
      .model flat, stdcall
      .stack 4096
      
      Include Irvine32.inc  ; 
      
      .data
      	
      .code
      main PROC
      	
      	mov al, 5h ;
      	mov bl, 0ffh ; 
      	mul bl ; 5h * ff 超过了AL表示的范围乘积AX=4FB, 标志寄存器CF=1, 0F=1
      
      	exit
      main ENDP
      
      END main                                                                                                                                                        
      
      ; vs2022 MASM环境代码示例
      .386
      .model flat, stdcall
      .stack 4096
      
      Include Irvine32.inc  ; 
      
      .data
      	
      .code
      main PROC
      	
      	mov ax, 0ff00h;
      	mov al, 5h
      	mov bx, 009ffh  ; 此时AX * BX 等于 ff05 * 9ff 等于 9F5 32FB, DX的值是9f5, AX的值是32fb
      					; 高位不为0,所以进位标志和溢出标志CF=1,OF=1
      	mul bx
      
      	exit
      main ENDP
      
      END main                                                                                                                                                        
      
      ; vs2022 MASM环境代码示例
      .386
      .model flat, stdcall
      .stack 4096
      
      Include Irvine32.inc  ; 
      
      .data
      	
      .code
      main PROC
      	
      	mov eax, 0ffff00h;
      	mov ebx, 002h  
      	mul ebx		; 此时EAX * EBX 等于 ffff00 * 2 等于 9F5 32FB, EDX的值是0, EAX的值是1FF FE00
      				; 高位EDX为0,所以进位标志和溢出标志CF=0,OF=0
      
      	exit
      main ENDP
      
      END main                                                                                                                                                        
      

IMUL指令有符号整数乘法

  • 与MUL指令不同,IMUL会保留乘积的符号,实现方法是将乘积的低半部分的符号位扩展到高半部分。X86指令集支持三种格式的IMUL指令:单操作数、双操作数、和三操作数

    1. 单操作数格式,乘积的高半部分是低半部分的符号扩展,进位标志位和溢出标志位置为1

      被乘数乘数乘积
      ALreg/mem8AX
      AXreg/mem16DX:AX
      EAXreg/mem32EDX:EAX
      ; vs2022 MASM环境代码示例
      .386
      .model flat, stdcall
      .stack 4096
      
      Include Irvine32.inc  ; 
      
      .data
      	
      .code
      main PROC
      	
      	mov al, 7fh;
      	mov bl, 03h  
      	imul bl		; 此时al * bl 等于 7f * 3 等于 17d, AX的值是17d, ah的值不是al的符号位扩展,则进位和溢出标志置为1
      				; 并且高位有效
      
      	mov al, -4
      	mov bl, 4
      	imul bl  ; -4 * 4乘积等会-16,乘积保存在AX中AH=FF ,AL = F0, AH是AL的符号位扩展,所以溢出和标志位置为0
      
      	exit
      main ENDP
      
      END main                                                                                                                                                        
      
    2. 双操作数格式, 32位模式下IMUL指令把乘积存放在第一个操作数中,这个操作数必须是寄存器。第二个操作数可以是寄存器,内存地址,立即数。格式如下所示

      1. IMUL reg16, reg/mem16
      2. IMUL reg16, imm8
      3. IMUL reg16, imm16
      4. IMUL reg32, reg/mem32
      5. IMUL reg32, imm8
      6. IMUL reg32, imm32
    3. 三操作数格式,32位模式下的将乘积保存在第一个操作数中。第二个操作数可以是16位寄存器或者内存操作数,它与第三个操作数相等,该操作数是一个8位或16位立即数。格式如下

      1. IMUL reg16, reg/mem16, imm8
      2. IMUL reg16, reg/mem16, imm16
      3. IMUL reg32, reg/mem32, imm8
      4. IMUL reg32, reg/mem32, imm32

DIV指令无符号除法,指令执行8位、16位、32位无符号数除法

  • 格式如下

    1. div reg/mem8
    2. div reg/mem16
    3. div reg/mem32
  • 被除数、除数、商、余数的关系如下

    被除数除数余数
    AXreg/mem8ALAH
    DX:AXreg/mem16AXDX
    EDX:EAXreg/mem32EAXEDX
  • 代码示例如下

    ; vs2022 MASM环境代码示例
    .386
    .model flat, stdcall
    .stack 4096
    
    Include Irvine32.inc  ; 
    
    .data
    	
    .code
    main PROC
    	
    	mov ax, 81h
    	mov bl, 8h
    	div bl  ; 执行之后AH(余数) = 1, AL(商) = 10H
    
    	exit
    main ENDP
    
    END main                                                                                                                                                        
    

IDIV指令,有符号数除法

  • 有符号数除法和无符号除法几乎一样,唯一不同点就是在执行除法之前,必须对被除数进行符号扩展。

  • 符号扩展指令CBW、CWD、CDQ

    • cbw、cwd、cdq指令分别将al、ax、eax扩展到ax、dx:ax、edx:eax


版权声明:本文为qmxz57原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。