1. 什么是符号扩展?为什么要用符号扩展?

所谓符号扩展,就是将数据的表示大小加倍,数值仍保持不变,即将符号位扩展到同样大小的寄存器空间中去,由两部分构成一个比原值表示大一倍的数。正数必须要0扩展,负数必须用1扩展。

为什么要进行符号扩展呢?这是因为有些指令对操作数位数的要求,例如倍长于除数的被除数,再如将数据位数加长以减少计算过程中的误差。另外,除法运算中规定

除数是BYTE,被除数存于AX,商存放在AL,余数放在AH

除数是WORD,被除数存于DX:AX,商存放在AX,余数放在DX

除数是DWORD,被除数存于EDX:EAX,商存放在EAX,余数放在EDX

被除数总是除数和商的两倍大小,由于余数的符号取决于被除数的符号,计算之后的余数存放在AH,DX,或者EDX中,那么执行除法之前,先将被除数的符号扩展到余数存放寄存器中,这也要求符号扩展。

事实上,在汇编语言里面,有符号数与无符号数计算,很多地方都分成了两套指令,进位与符号操作,都交由程序员来判断和操作,符号扩展正是这一设计思想的体现。

2. 符号扩展指令及应用示例

2.1  CBW(Convert Byte to Word):

规定将AL中的符号扩展到AX中,这是规定死的,执行这个指令就将AL中的符号扩展到AX中了。通过符号扩展,将AL的操作数大小扩大1倍,字节表示的数用字表示,将结果存入AX中。将AL中的符号位第7位,复制到AH中的每一位。例如

XOR EAX,EAX

MOV AL,-128

此时EAX=0x80二进制10000000

CBW

此时EAX=0xFF80进制11111111 10000000符号位1,高8位用符号位1全部填充。

2.2  CWD(Convert Word to Doubleword):

规定将AX中的符号扩展到DX中,执行这个指令就将AX中的符号扩展到DX中了,那为什么不直接将AX中的符号扩展到EAX中,而要那么麻烦地扩展到DX中,再用DX:AX来表示一个有符号数呢,例如,后面的CWDE就是这么干的?估计是在符号扩展指令出来时,还没有32位机,如8086就是16位cpu,也就没有EAX寄存器,只能用两个16位寄存器来表示32位数了,后续32位为了兼容16位时写的程序,也就保留了这种操作方法。另外用于在有符号除法运算中,AX存放商,DX存放余数,不将符号扩展到DX中,IDIV指令是不会将负号自动填进去的,会使计算结果不正确。

通过符号扩展,将AX中的操作数大小扩大1倍,字表示的数用双字表示,将结果存入DX:AX中,用两个字寄存器存储1个双字的数。例如

XOR EAX,EAX

XOR EDX,EDX

MOV AX,-32768

此时AX=0x8000二进制10000000 00000000

CWD

此时AX=0x8000进制10000000 00000000符号位1,而DX=0xFFFF,即符号位1被填充到了DX。

2.3  CDQ(Convert Doubleword to Quadword):

规定将EAX中的符号扩展到EDX中,执行这个指令就将EAX中的符号扩展到EDX中了。同样,当两个32位有符号数相乘时,符号位就超出了32位表示的范围,像前一样,用两个寄存器EDX:EAX来表示这个乘法的结果,从而得到正确的计算结果。同理,64位出现后,为了兼容32位的程序,也保留了这种操作。同样,在有符号除法运算中,EAX存放商,EDX存放余数,不将符号扩展到EDX中,IDIV指令是不会将负号自动填进去的,会使计算结果不正确。通过符号扩展,将EAX中的操作数大小扩大1倍,双字表示的数用四字表示,将结果存入EDX:EAX中,用两个双字寄存器存储1个四字的数。例如

XOR EAX,EAX

XOR EDX,EDX

MOV EAX, -2147483648

此时EAX=0x8000 0000二进制10000000 00000000 00000000 00000000

CWD

此时EAX=0x80000000进制10000000 00000000 00000000 000000000符号位1,而EDX=0xFFFFFFFF,即符号位1被填充到了EDX。

2.4  CQO(Convert Quadword to )

规定将RAX中的符号扩展到RDX中去,这是64位cpu模式下使用的指令。用以表示128位的数据,因为两个64位数操乘法运算超过64位的范围,采用以上的表示方法。同样,在有符号除法运算中,RAX存放商,RDX存放余数,不将符号扩展到RDX中,IDIV指令是不会将负号自动填进去的,会使计算结果不正确。通过符号扩展,将RAX中的操作数大小扩大1倍,四字表示的数用八字表示,将结果存入RDX:RAX中,用两个四字寄存器存储1个八字的数。例如

XOR RAX,RAX

XOR RDX,RDX

MOV RAX, -9223372036854775808

此时RAX=0x8000000000000000二进制

1000000000000000000000000000000000000000000000000000000000000000

CQO

此时RAX=0x8000000000000000 符号位1,而RDX=0xFFFFFFFFFFFFFFFF,即符号位1被填充到了RDX。

2.5  CWDE(Convert Word to Doubleword):

这个E(Extension)应该是指相对于CWD的扩展,是稍后面加的指令,CWD指令出现的时间比CWD早。规定将AX中的符号扩展到EAX中,执行这个指令就将AX中的符号扩展到EAX中了。

CWDE同CWD,只是符号位是直扩展到EAX的高16位中了。

2.6  CDQE(Convert Doubleword to Quadword):

这个E(Extension)应该是指相对于CWQ的扩展,同样,CWD指令出现的时间比CDQE早。

规定将EAX中的符号扩展到RAX中,执行这个指令就将EAX中的符号扩展到RAX中了。

CDQE同CDQ,符号被扩展到RAX的高32位中了。

2.7 MOVZX指令将源操作数的内容复制到目的操作数中,并将该值零扩展至16位或32位。该指令仅适用于无符号整数。

为什么要有这个指令呢,因为MOV指令不能将一个较小的操作数复制到一个较大的操作数。

类为MOV指令要求两个操作数必须一样大。比如将一个较小的操作数在寄存上执行MOV操作,则寄存器的高位没有被覆盖,这个时候我们取整个寄存器值作为MOV的结果是不对的,例如

data1 BYTE 1

data2 WORD ?

XOR EAX,EAX

MOV AX,0FFFFH

MOV AL,data1

MOV data2,AX

这个时候,data2变成了FF01,而不是1。要得到正确的结果,可以有多种方法

比如,先将高位清零

XOR EAX,EAX

MOV AL,data1

MOV data2,AX

这样data2=1了

或者就直接使用这个指令

MOV AX,0FFFFH

MOVZX AX,data1

MOV data2,AX

2.8 MOVSX指令将源操作数的内容复制到目的操作数中,并将该值符号扩展至16位或32位。该指令仅适用于有符号整数。例如

data1 SBYTE -1

data2 SWORD ?

XOR RAX,RAX

MOV AL,data1

MOV data2,AX

这个时候,data2的值为255了,而不是-1,也就是MOV并没有把FF当成有符号数,而是当作值了,那么用MOVSZ就不一样了。

XOR RAX,RAX

MOVSX AX,data1

MOV data2,AX

这个时候data2=-1,是正确的结果。

汇编语言符号扩展指令及应用示例相关推荐

  1. 学习笔记(符号扩展指令:SXTB和SXTH)

    前言 这些笔记主要是记录自己在学习CM3汇编中的一些问题(因为我们老师上stm32的嵌入式课是从基础汇编开始讲的,CM3汇编在网上能查到的例子讲解有点少,哭!),其中可能借鉴过网上一些大佬的文章,如果 ...

  2. 汇编语言逻辑“或”指令与应用示例:OR (Logical Inclusive OR)和 XOR (Logical Exclusive OR)

    1. 定义: (1) OR是或运算,A OR B的结果:当A.B中只要有一个或者两个都为1时,结果为1,否则为0.     原则:两个输入有真则真.     汇编指令OR,称为逻辑包含"或& ...

  3. Win32ASM学习[14]:符号扩展指令: CBW,CWDE,CDQ,CWD

    ---------------------------------------------------------------------------------------------------- ...

  4. cbw与cwd符号扩展的实际意义

    符号扩展的实际意义 符号扩展的实际意义是什么? 将数据进行符号扩展是为了产生一个位数加倍.但数值大小不变的结果,以满足有些指令对操作数位数的要求,例如倍长于除数的被除数,再如将数据位数加长以减少计算过 ...

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

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

  6. 汇编语言-013(DAS 、DAA与DAS、QWORD类型用SBB借位减法、编写指令将AX符号扩展到EAX,不能使用CWD、用SHR和条件判断指令将AL循环右移一位、SHLD、压缩十进制转换)

    1:DAS : SUB或SBB在AL中生成二进制结果,DAS(减法后的十进制调整)转压缩十进制格式 .386 .model flat,stdcall.stack 4096 ExitProcess PR ...

  7. RISC-V扩展指令示例

    自定义RISC-V扩展指令 要实现协处理器的设计,必然会涉及到新的指令.比如蜂鸟书籍<手把手教你设计CPU--RISC-V处理器篇>[1]第十六章中实现3*3矩阵的行列和运算时就定义了三条 ...

  8. 汇编语言的符号拓展指令CBW、CWD、CDQ、CWDE、CDQE

    符号拓展指令,使用符号位拓展数据类型. cbw 使用al的最高位拓展ah的所有位,(最高位即为符号位) cwd使用ax的最高位拓展dx的所有位 cdq使用eax的最高位拓展edx的所有位 cwde使用 ...

  9. std在汇编语言是什么指令_汇编语言指令

    汇编指令英文全称 1.通用数据传送指令 MOV----> move MOV dest,src ;dest←src MOV指令把一个字节或字的操作数从源地址src传送至目的地址dest. MOVS ...

最新文章

  1. 图例放在图的外面_Origin做双Y轴箱型图(图文讲解)
  2. MYSQL数据库备份还原,并还原到最新状态(mysqldump,xtrabackup)
  3. oracle db file sequential read,db file sequential read等待事件
  4. 【POJ - 3273 】Monthly Expense (二分,最小最大值)
  5. linux ddd yum,Linux环境ddd安装与使用
  6. Bailian2729 求12以内n的阶乘 Bailian2730 求20以内n的阶乘【递推】
  7. 【JavaScript创建对象】
  8. Statistics Pro for Mac(统计学软件)
  9. OpenWrt 把SD卡挂载到 /overlay
  10. Linux——就业方向选择、学习内容、学习方法
  11. openssl自建CA服务器自签证书服务器
  12. mysql中secure_file_priv=不生效的问题
  13. 戏如人生,人生如戏!
  14. redis cluster 集群 HA 原理和实操(史上最全、面试必备)
  15. android画板案例
  16. Combining Visual Cues with Interactions for 3D–2D Registration in Liver Laparoscopy翻译
  17. Android 保持屏幕不熄屏
  18. vue : 无法加载文件 C:\Users\lihongjie\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 htt ps:/go.micr
  19. DASCTF Oct X 吉林工师-欢迎来到魔法世界-misc-魔法少女的迷音(复现)
  20. Linux 那么多命令的来源

热门文章

  1. 短视频防止侵权之路——今抖云创
  2. android手机联调,安卓手机联调Chrome调试H5页面
  3. 一分钟搞定Spring AOP实现权限控制
  4. 2d 互相关算法-python
  5. ChIP-seq文章 | Frontiers in Plant Science发表揭示青稞对白粉病的抗性机制
  6. 华硕 ROG PG27UQR 电竞显示器参数 华硕 ROG PG27UQR 评测
  7. OWASP TOP 10的风险分析、预防措施以及攻击范例(下)
  8. RK3568-USB摄像头实时AI物品识别
  9. Python程序员必读的一本书《Python编程导论》,豆瓣评分9.0以上
  10. 微信小程序之生命周期