有符号除法几乎与无符号除法相同,只有一个重要的区别:在执行除法之前,必须对被除数进行符号扩展。

符号扩展是指将一个数的最高位复制到包含该数的变量或寄存器的所有高位中。为了说明为何有此必要,让我们先不这么做。下面的代码使用 MOV 把 -101 赋给 AX,即 DX:AX 的低半部分:

.data

wordVal SWORD -101 ; 009Bh

.code

mov dx, 0

mov ax, wordVal ; DX:AX = 0000009Bh (+155

mov bx, 2 ; BX 是除数

idiv bx ; DX:AX除以BX (有符号操作)

可惜的是,DX:AX 中的 009Bh 并不等于 -101,它等于 +155。因此,除法产生的商为 +77,这不是所期望的结果。而解决该问题的正确方法是使用 CWD( 字转双字 ) 指令,在进行除法之前在 DX:AX 中对 AX 进行符号扩展:

.data

wordVal SWORD -101 ; 009Bh

.code

mov dx, 0

mov ax, wordVal ; DX:AX = 0000009Bh (+155)

cwd ; DX:AX = FFFFFF9Bh (-101 )

mov bx, 2

idiv bx

x86 指令集有几种符号扩展指令。首先了解这些指令,然后再将其应用到有符号除法指令 IDIV 中。

符号扩展指令(CBW、CWD、CDQ)

Intel 提供了三种符号扩展指令:CBW、CWD 和 CDQ。CBW(字节转字)指令将 AL 的符号位扩展到 AH,保留了数据的符号。如下例所示,9Bh(AL 中)和 FF9Bh (AX 中)都等于十进制的 -101:

.data

byteVal SBYTE -101 ; 9Bh

.code

mov al, byteVal ; AL = 9Bh

cbw ; AX = FF9Bh

CWD(字转双字)指令将 AX 的符号位扩展到 DX:

.data

wordVal SWORD -101 ; FF9Bh

.code

mov ax, wordVal ; AX = FF9Bh

cwd ; DX:AX = FFFFFF9Bh

CDQ(双字转四字)指令将 EAX 的符号位扩展到 EDX:

.data

dwordVal SDWORD -101 ; FFFFFF9Bh

.code

mov eax, dwordVal

Cdq ; EDX:EAX = FFFFFFFFFFFFFF9Bh

IDIV 指令

IDIV(有符号除法)指令执行有符号整数除法,其操作数与 DIV 指令相同。执行 8 位除法之前,被除数(AX)必须完成符号扩展。余数的符号总是与被除数相同。

【示例 1】下述指令实现 -48 除以 5。IDIV 执行后,AL 中的商为 -9,AH 中的余数为 -3:

.data

byteVal SBYTE -48 ;D0 十六进制

.code

mov al, byteVal ;被除数的低字节

cbw ;AL扩展到AH

mov bl,+5 ;除数

idiv bl ;AL = -9, AH = -3

下图展示了 AL 是如何通过 CBW 指令符号扩展为 AX 的:

为了理解被除数的符号扩展为什么这么重要,现在在不进行符号扩展的前提下重复之前的例子。下面的代码将 AH 初始化为 0,这样它就有了确定值,然后没有用 CBW 指令转换被除数就直接进行了除法:

.data

byteVal SBYTE -48 ;D0 十六进制

.code

mov ah, 0 ;被除数高字节

mov al, byteVal ;被除数低字节

mov bl, +5 ;除数

idiv bl ;AL = 41z AH = 3

执行除法之前,AX=00D0h ( 十进制数 208)。 IDIV 把这个数除以 5,生成的商为十进制数 41,余数为3。这显然不是正确答案。

【示例 2】16 位除法要求 AX 符号扩展到 DX。下例执行 -5000 除以 256:

.data

wordVal SWORD -5000

.code

mov ax, wordVal ;被除数的低字

cwd ;AX扩展到DX

mov bx, +256 ;除数

idiv bx ;商 AX=-19,余数 DX=-13 6

【示例 3】32 位除法要求 EAX 符号扩展到 EDX。下例执行 50 000 除以 -256:

.data

dwordVal SDWORD +50000

.code

mov eax, dwordVal ;被除数的低双字

cdq ;EAX 扩展至q EDX

mov ebx, -256 ;除数

idiv ebx ;商 EAX=-195,余数 EDX=+80

执行 DIV 和 IDIV 后,所有算术运算状态标志位的值都不确定。

除法溢出

如果除法操作数生成的商不适合目的操作数,则产生除法溢出 (divide overflow)。这将导致处理器异常并暂停执行当前程序。例如,下面的指令就产生了除法溢出,因为它的商 (100h) 对 8 位的 AL 目标寄存器来说太大了:

mov ax,1000h

mov bl,10h

div bl                   ; AL无法容纳100h

运行这段代码时,Visual Studio 就会产生如下所示的结果错误。如果试图运行除以零的代码,也会显示相同的对话框。

Unhandled exception at 0x00401016 in Project.exe:0xC0000095:Integer overflow.

对此有个建议:使用 32 位除数和 64 位被除数来减少出现除法溢出条件的可能性。如下面的代码所示,除数为 EBX,被除数在 EDX 和 EAX 组成的 64 位寄存器对中:

mov eax,1000h

cdq

mov ebx,10h

div ebx               ; EAX = 00000100h

要预防除以零的操作,则在进行除法之前检查除数:

mov ax, dividend

mov bl, divisor

cmp bl, 0 ;检查除数

je NoDivideZero ;为零?显不错误

div bl ;不为零:继续

.

.

NoDivideZero: ;显示 "Attmpt to divide by zero"

matlab符号函数的除法,汇编语言IDICV指令:有符号数除法相关推荐

  1. 汇编语言---乘法指令及符号扩展

    汇编语言---有符号数乘法指令 介绍 格式及功能介绍 无符号数乘法指令 有符号数乘法指令 符号扩展及符号扩展语句 符号扩展 符号扩展语句 例子 无符号相乘 有符号数相乘 这是本文的重点: 有符号数相乘 ...

  2. matlab把向量转化为矩阵,MATLAB小函数:将列向量转化为0-1矩阵

    MATLAB小函数:将列向量转化为0-1矩阵 将列向量转化为0-1矩阵,例如 A = 1 2 1 5 3 4 1 4 3 转换为: B = 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 ...

  3. matlab常用函数与常用指令大全

    matlab常用函数与常用指令大全 matlab常用函数- - 1.特殊变量与常数 ans 计算结果的变量名 computer 确定运行的计算机 eps 浮点相对精度 Inf 无穷大 I 虚数单位 i ...

  4. matlab数组求一阶导数,用matlab求符号函数数组或函数矩阵的导数实例教程

    用matlab求符号函数数组或函数矩阵的导数实例教程 在符号矩阵中,矩阵的每个元素都可以存放符号函数,这是对符号函数数组的求到运算是对数组元素逐个进行的.接下来就以实例向大家介绍一下用matlab对符 ...

  5. matlab符号函数绘图法_《MATLAB符号运算及其应用》(黄忠霖著).pdf

    <MATLAB符号运算及其应用>(黄忠霖著).pdf [General Information] 书名=MATLAB符号运算及其应用 作者=黄忠霖,黄京编著 页数=425 出版社=北京市: ...

  6. 7.2 matlab符号微积分(符号函数的极限、导数和积分)

    1.符号函数的极限 求符号函数极限的命令为limit,其调用格式为: limit(f,x,a) 即求函数f关于变量x在a点的极限.若x省略,则采用系统默认的自变量.a的默认值为0. limit函数的另 ...

  7. matlab 绘制符号函数,DAY8 MATLAB学习笔记—simulink入门、MATLAB符号函数的图形绘制...

    如何打开simulink: 启动simulink: 先打开MATLAB软件界面 第一步打开simulink 第二步在command windows输入 simulink然后enter,等待 有很多模块 ...

  8. matlab出错及解决办法,Linux下使用Matlab符号函数出错的解决办法

    在教新版本Linux中使用Matlab的符号函数库及相关功能时,有时候可能会出错,错误的代码大致为: Unable to load mex file: /usr/local/matlab/toolbo ...

  9. Matlab多项式和符号函数简介

    本篇博客是B站教学视频的学习笔记,视频教程地址:https://www.bilibili.com/video/BV1hE411Q7T4,Up主讲的很好,部分内容有删减.部分内容为我自己的理解,由于本人 ...

最新文章

  1. 百度离职员工吐槽:整天除了工作还要演好戏,拍马屁,心太累!
  2. 【PC工具】注意安全,建议使用:安全软件,谷歌输入法下载
  3. 还有多少时间可以用来读书
  4. CCFCSP 2018年9月 -- 部分题目
  5. 结构体的一些形式理解
  6. Office EXCEL 中如何让一个单元格的数据链接到另一个工作表的数据
  7. 如何优雅的关闭 Spark Streaming 程序(2种思路)
  8. Spark记录-Scala记录(基础程序例子)
  9. FZU_1683 矩阵快速幂 求和
  10. Neo4j HA环境配置
  11. 【学习框架】jeeSite 【maven项目】导入后转成web项目 【转载加原创】
  12. c语言实现http下载器
  13. Redis雪崩效应的解决方案(转)
  14. 第10章 vim程序编辑器
  15. qq邮箱foxmail imap服务器,开通IMAP服务 用Foxmail远程遥控QQ邮箱
  16. Spring Data JPA 的动态查询和一对多及多对多查询
  17. 2019支付宝小程序技术专场招募
  18. 计算机视频的压缩方式,如何在电脑上对视频进行压缩?一分钟教你学会视频压缩方法...
  19. 淘宝API商品详情接口,通过商品ID获取商品名称,淘宝主图,价格,颜色规格尺寸,库存,SKU等
  20. 用python画一只小狗

热门文章

  1. JAVA注解 | 可重复元注解@Repeatable
  2. HWND、HANDLE、HMODULE、HINSTANCE的区别
  3. 最新版南风表情包小程序独立版源码 独家最火表情包小程序源码+完整后台API+小程序前端
  4. 无线监控出观服务器异常,手机连监控连接服务器异常什么原因
  5. ICPC 2018 焦作赛区网络预赛G Give Candies 组合数学隔板法+欧拉降幂
  6. 字符串和字符串结束标志
  7. @PreAuthorize 不起作用
  8. verilog 双向口使用
  9. 2015-06-12
  10. 魅族手机鸿蒙系统,魅族宣布接入鸿蒙系统,被网友吐槽蹭热点