x86汇编_DIV / IDIV除法指令_笔记53
无符号除法
32 位模式下,DIV(无符号除法)指令执行 8 位、16 位和 32 位无符号数除法,结果以余数和商的方式表现。格式如下:
DIV 8位寄存器或内存
DIV 16位寄存器或内存
DIV 32位寄存器或内存
被除数 | 除数 | 商 | 余数 |
AX | reg/mem8 | AL | AH |
DX:AX | reg/mem16 | AX | DX |
EDX:EAX | reg/mem32 | EAX | EDX |
根据以上表格可以总结出,div指令,当操作数是8位二进制,被除数就一定是16位,操作数是16位则被除数一定32位(两个16进制寄存器连起来)。也就是说被除数永远大于除数。
下述指令执行 8 位无符号除法 (83h/2),生成的商为 41h,余数为 1:
-
mov ax, 0083h ; 被除数
-
mov bl, 2 ; 除数
-
div bl ; AL = 41h, AH = Olh
下述指令执行 16 位无符号除法 (8003h/100h),生成的商为 80h,余数为 3。DX 包含的是被除数的高位部分,因此在执行 DIV 指令之前,必须将其清零:
-
mov dx, 0 ; 清除被除数高16位
-
mov ax, 8003h ; 被除数的低16位
-
mov ex, 100h ; 除数
-
div ex ; AX = 0080h, DX = 0003h
下述指令执行 32 位无符号除法,其除数为内存操作数:
-
.data
-
dividend QWORD 0000000800300020h
-
divisor DWORD 00000100h
-
.code
-
mov edx, DWORD PTR dividend 4 ; 高双字
-
mov eax, DWORD PTR dividend ; 低双字
-
div divisor ; EAX = 08003000h, EDX = 00000020h
下面的 64 位除法生成的商 (0108 0000 0000 3330h) 在 RAX 中,余数 (0000 0000 0000 0020h) 在 RDX 中。请注意,由于被 64k 除,被除数中的每个十六进制数字是如何右移 4 位的。(若被 16 除,则每个数字只需右移一位。):
-
.data
-
dividend_hi QWORD 0000000000000108h
-
dividend_lo QWORD 0000000033300020h
-
divisor QWORD OOOOOOOOOOOlOOOOh
-
.code
-
mov rdx, dividend_hi
-
mov rax, dividend_lo
-
div divisor ; RAX = 0108000000003330
-
; RDX = 0000000000000020
有符号数除法
有符号除法与无符号几乎相同,但是在计算前必须对被除数进行符号扩展。
指令 | 全称 | 说明 |
cbw | convert byte to word | 将AL的符号位扩展到AH |
cwd | convert word to doubleword | 将AX的符号位扩展到DX |
cdq | convert doubleword to quadword | 将EAX的符号位扩展到EDX |
-
.DATA
-
byte_val SBYTE -101
-
-
.CODE
-
mov al, byte_val ; AL = 9Bh
-
cbw ; AX = FF9Bh
执行有符号除法前必须对被除数进行符号扩展,否则除法不会得到正确结果。具体先看以下例子:
-
.386
-
.model flat,stdcall
-
.stack 4096
-
ExitProcess proto,dwExitCode:dword
-
INCLUDE Irvine32.inc
-
-
.data
-
wordval sword -101
-
-
.code
-
main PROC
-
nop
-
mov dx, 0
-
mov ax, wordval
-
;此时DX:AX=0000:FF9B,根据补码规则应当被解释为正65435。但我们需要的是-101。
-
mov bx, 2
-
idiv bx ; 65435/2=32717余1
-
invoke ExitProcess,0
-
main ENDP
-
-
end main
如果使用CBW指令:
-
.data
-
wordval sword -101
-
-
.code
-
main PROC
-
nop
-
mov dx, 0
-
mov ax, wordval
-
cwd; DX:AX=FFFF:FF9B,这样的才能保证被除数是负101,否则会被解释为正65435。
-
mov bx, 2
-
idiv bx
-
invoke ExitProcess,0
-
main ENDP
除法溢出
如果除法的商放不下容纳它的位置,就会产生除法溢出,这将导致处理器异常并暂停执行当前程序,以下指令产生了溢出,因为AL放不下十六进制数100h。
如果试图除以0,也会产生类似错误。
为了避免除数为0,可以用CPU跳转语句,发现除数是0就跳过div指令:
-
.code
-
main PROC
-
nop
-
mov ax, 20
-
mov bl, 0
-
cmp bl, 0
-
je NoDivideZero
-
div bl
-
nodividezero:
-
invoke ExitProcess,0
-
main ENDP
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggeiea
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01