首页 > 编程语言 >汇编div的注意

汇编div的注意

时间:2023-11-27 11:12:11浏览次数:40  
标签:汇编 符号 16 mov 注意 div 除法 被除数

无符号除法

32 位模式下,DIV(无符号除法)指令执行 8 位、16 位和 32 位无符号数除法,结果以余数和商的方式表现。格式如下:

DIV 8位寄存器或内存
DIV 16位寄存器或内存
DIV 32位寄存器或内存

被除数除数余数
AXreg/mem8ALAH
DX:AXreg/mem16AXDX
EDX:EAXreg/mem32EAXEDX

根据以上表格可以总结出,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

有符号数除法

有符号除法与无符号几乎相同,但是在计算前必须对被除数进行符号扩展。

符号扩展指令
指令全称说明
cbwconvert byte to word将AL的符号位扩展到AH
cwdconvert word to doubleword将AX的符号位扩展到DX
cdqconvert doubleword to quadword将EAX的符号位扩展到EDX
.DATA
byte_val SBYTE -101

.CODE
mov al, byte_val ; AL = 9Bh
cbw ; AX = FF9Bh

CBW指令,将AL的最高位值填充到AH,AH原来的内容被替换掉。

执行有符号除法前必须对被除数进行符号扩展,否则除法不会得到正确结果。具体先看以下例子:

.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

标签:汇编,符号,16,mov,注意,div,除法,被除数
From: https://www.cnblogs.com/luo9tian/p/17858827.html

相关文章

  • Codeforces Round 911 (Div. 2) A
    真的太菜了……题目链接:Problem-A-Codeforces//Problem:A.CoverinWater//Contest:Codeforces-CodeforcesRound911(Div.2)//URL:https://codeforces.com/contest/1900/problem/0#//MemoryLimit:256MB//TimeLimit:1000ms////PoweredbyCPEd......
  • 在visual studio反汇编得出的函数之间的一些管旭
    非裸函数执行过程002018D1push3002018D3push2002018D5push1//将三个数压入栈中002018D7callstd::basic_ostreamchar,std::char_traits<char>::sentry::sentry(0201497h)002018DCaddesp,0Ch//ebp表示栈底,esp表示栈顶,前面三个数将esp减去了0x0C,现在需要加上0......
  • [Codeforces] CF1799B Equalize by Divide
    序列操作(divide.cpp)—CF1799B—1200题目描述给您一个\(a_1,a_2,\dotsa_n\)这样的正整数数组,您可以对它进行多次(可以是零次)这样的操作:选择两个索引\(i,j(1\leqi,j\leqn,i\neqj)\);将\(a_i\)赋值为\(\lceil\frac{a_i}{a_j}\rceil\)。这里的\(\lceilx\rceil\)......
  • CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
    CodeTONRound7(Div.1+Div.2,Rated,Prizes!)A-JaggedSwaps解题思路:若\(a[1]=1\),则可以。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;typedefpair<int,int>pii;#definefifirst#definesesecondvoidsolve(){......
  • CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
    CodeTONRound7(Div.1+Div.2,Rated,Prizes!)A-JaggedSwapsintmain(){IOS;for(cin>>_;_;--_){cin>>n;rep(i,1,n)cin>>a[i];while(true){boolf=0;rep(i,......
  • CodeTON Round 7 (Div. 1 + Div. 2) 解题报告
    CodeTONRound7(Div.1+Div.2)ContestLink广告:本场比赛博主使用了CCH完成,体验很好,推荐高rating用户使用(低rating受cloudflare影响很大)。A.JaggedSwaps\(\text{Status:\color{green}+\color{black}00:03}\)结论:输出YES当且仅当\(a_1=1\)。证明:如......
  • CF 158 (Rated for Div
    CF-158这次比赛较上次也是有进步,成功地多AC了一道题。但第4题也是很遗憾只差一点了。A.LineTrip题意:车在数轴上从$0$点到达$x$点又返回$0$点,有$k$点的油,可以走$k$个单位,在数轴上$a_1,a_2,a_3...a_n$处可以加油到$k$点,$0$点处和$x$点处无法加油,问$k$的最小值。思路:那么根据题......
  • AcWing 1126. 最小花费 (从终点方向求的dij -> 注意本题这么求就必须判断两点之间是否
    package算法提高课;importjava.util.Arrays;importjava.util.Scanner;publicclassacw1126{staticintn,m;staticint[][]g;staticdouble[]d;staticboolean[]st;privatestaticvoidinit(){g=newint[n+10][n+10];......
  • CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
    CodeTONRound7(Div.1+Div.2,Rated,Prizes!)基本情况A题花了快半小时,做出来了但是不如正解。B题又是老毛病,一条路走到黑,爆搜打出来超时就死命想剪枝和记忆化,没想过换方法(觉得贪心不可行)。A-JaggedSwaps我的解法没啥好说的,纯模拟。看到\(n\leq10\)知道能过。......
  • Educational Codeforces Round 158 (Rated for Div. 2)
    EducationalCodeforcesRound158(RatedforDiv.2)基本情况A题很水,几分钟秒了。B题想到一个解,被自己hack掉之后没有重新想,一直想在自己一开始的基础上改好,结果最后B都没拿下。B.ChipandRibbon我的思路其实也是找规律,根本没严谨地证明正确性。不应该一条路走到黑的......