汇编语言-011(无符号乘法指令MUL、有符号乘法指令IMUL、对比MUL乘法指令与SHL移位方式、符号位扩展指令,CBW,CWD,CDQ、DIV 无符号除法指令、IDIV 有符号除法指令)

1:无符号乘法指令MUL

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
val1 WORD 2000h
val2 WORD 0100h
.code
main PROC
   
   ;8位乘法
   mov al,5h  ;被乘数
   mov bl,10h
   mul bl     ;AX = 0050h ,CF,OF = 0

   ;16位乘法
   mov ax,val1
   mul val2   ;DX:AX = 00200000h ,CF ,OF= 1 高部分不为零0了,CF,OF=1

   mov eax,12345h
   mov ebx,1000h
   mul ebx   ;EDX:EAX = 0000000012345000 ,CF,OF = 0


   
   INVOKE ExitProcess,0
main ENDP
END main

2:有符号乘法指令IMUL 单个操作数情况

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.code
main PROC

  mov al,48
  mov bl,4
  imul bl    ;AX = 00C0h ,OF=1   因为AH不是AL的符号扩展,因此OF =1

  mov al,-4
  mov bl,4
  imul bl  ;AX = FFF0h,OF =0 因为AH是AL的扩展,OF清零

  mov ax,48
  mov bx,4
  imul bx   ;DX:AX = 000000C0h,OF = 0 ;因为DX是AX的符号扩展,因此OF=0

  mov eax,+4823424
  mov ebx,-423
  imul ebx  ;EDX:EAX = FFFFFFFF86635D80h, OF = 0,因为EDX是EAX的符号扩展,OF = 0
  INVOKE ExitProcess,0
main ENDP
END main

3:有符号乘法指令IMUL 两个操作数情况, 三个操作数情况

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
word1 SWORD 4
dword1 SDWORD 4


.code
main PROC
   
   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指令的目的操作数大小与乘积相同
   ;因此会出现符号溢出
   mov ax,-32000
   imul ax,2     ;OF = 1 因为-64000不适合16位目的操作数,换成32就不会

   ;三操作数
   imul bx,word1,-16  ;BX = word1 * -16
   imul ebx,dword1,-16 ;EBX = dword1 * -16
   imul ebx,dword1,-2000000000 ;符号溢出


   INVOKE ExitProcess,0
main ENDP
END main

4:对比MUL乘法指令与SHL移位方式的执行时间对比 (在现在大部分处理器执行时间都差不多了)

include Irvine32.inc

.stack 4096
ExitProcee PROTO,dwExitCode:DWORD

LOOP_COUNT = 0FFFFFFFFh
.data
intval DWORD 5
startTime DWORD ?

.code
main PROC
   call GetMseconds  ;获取开始时间
   mov startTime,eax
   mov eax,intval
   call mult_by_shifting
   call GetMseconds
   sub eax,startTime
   call WriteDec
   call Crlf

    call GetMseconds  ;获取开始时间
   mov startTime,eax
   mov eax,intval
   call mult_by_MUL
   call GetMseconds
   sub eax,startTime
   call WriteDec
   INVOKE ExitProcess,0
main ENDP

mult_by_shifting PROC
    
	mov ecx, LOOP_COUNT
L1:
   push eax  ;保存原始EAX
   mov ebx,eax
   shl eax,5
   shl ebx,2
   add eax,ebx
   pop eax  ;恢复EAX
   loop L1
   ret

mult_by_shifting ENDP

mult_by_MUL PROC
    mov ecx,LOOP_COUNT
L1:
   push eax  ;保存原始EAX
   mov ebx,36
   mul ebx
   pop eax  ;恢复EAX
   loop L1
   ret
mult_by_MUL ENDP


END main

5:DIV 无符号除法指令

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
dividend QWORD 0000000800300020h
divisor  DWORD 00000010h

.code
main PROC

   ;8位 AL商,AH余数
   mov ax,0083h  ;被除数
   mov bl,2      ;除数
   div bl        ;AL = 41h  ,AH =01h

   ;16位,AX商,DX余数
   mov dx,0      ;清除被除数高16位
   mov ax,8003h  
   mov cx,100h
   div cx        ;AX=0080h  DX=0003h

   ;32位 EAX商,EDX 余数
   mov edx,DWORD PTR dividend +4  ;高双字
   mov eax,DWORD PTR dividend     ;低双字
   div divisor       ;EAX = 08003000h  EDX = 00000020h

   INVOKE ExitProcess,0
main ENDP
END main

6:符号位扩展指令,CBW,CWD,CDQ

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
byteVal SBYTE -101
wordVal SWORD -101
dwordVal SDWORD -101

.code
main PROC
  
  mov al,byteVal  ;AL = 9Bh
  cbw             ;AX = FF9Bh

  mov ax,wordVal  ;AX = FF9Bh
  cwd             ;DX:AX = FFFFFFF9Bh

  mov eax,dwordVal ;EAX = FFFFFF9Bh
  cdq              ;EDX:EAX = FFFFFFFFFFFFFF9Bh

  INVOKE ExitProcess,0
main ENDP
END main

7:IDIV 有符号除法指令

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
byteVal SBYTE -48
wordVal SWORD -5000
dwordVal SDWORD +50000

.code
main PROC
   mov al,byteVal  ;被除数低字节
   cbw             ;扩展到AH
   mov bl,+5
   idiv bl   ;AL = -9 ,AH =-3

   mov ax,wordVal  ;被除数低字
   cwd             ;扩展到DX
   mov bx,+256 
   idiv bx         ;商AX = -19  ,余DX = -136

   mov eax,dwordVal
   cdq
   mov ebx,-256
   idiv ebx   ;EAX = -195  EDX = +80
   INVOKE ExitProcess,0
main ENDP
END main

8:进行除法时,检查除数不能为0

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
dividend WORD 0083h
divisor BYTE 2

.code
main PROC
   mov ax,dividend
   mov bl,divisor
   cmp bl,0
   je NoDivideZero  ;为零就不进行除
   div bl

NoDivideZero:
   INVOKE ExitProcess,0
main ENDP
END main

9:计算算式 var4 = (var1 + var2)*var3

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
var1 DWORD 10
var2 DWORD 20
var3 DWORD 30
var4 DWORD ?


.code
main PROC

  ;var4 = (var1 + var2)*var3
   mov eax,var1
   add eax,var2
   mul var3
   jc tooBig   ;判断EAX是否放得下
   mov var4,eax
   jmp next
tooBig:
next:
   INVOKE ExitProcess,0
main ENDP
END main

10:计算算式 var4 = (var1 * -5) / (-var2 % var3)

.386
.model flat,stdcall

.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

.data
var1 DWORD 10
var2 DWORD 20
var3 DWORD 30
var4 DWORD ?


.code
main PROC

  ;var4 = (var1 * -5) / (-var2 % var3)
   
   mov eax,var2
   neg eax
   cdq
   idiv var3  ;EDX=余数
   mov ebx,edx 
   mov eax,-5
   imul var1  ;EDX:EAX = 左边表达式结果
   idiv ebx
   mov var4,eax
   INVOKE ExitProcess,0
main ENDP
END main
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值