特殊的算术操作指令详解

特殊的算术操作指令详解

前言

上一讲,我们说了常见的算术与逻辑运算指令,其中比较有特点的是leal指令,本次我们在介绍几个较特殊的操作指令,这些指令可以让只有32位的寄存器存储64位的数据是不是很吊?

正文

我们来看一下这些指令的大致介绍,如果又仔细看过上一讲的内容,可能会发现这里的指令有些眼熟,但是他们的作用却截然不同.以下是书中的一张概图:

第一个指令很眼熟吧,他就是我们上一章说的imull乘法指令的双字形式.不过可以看出,这里的imull指令已经完全变了了个人,他将结果存入两个寄存器.接下来,我们来看看这些指令.

imull,mull指令

这两个指令一看就是双胞胎,他们一个负责有符号位全64位乘法,一个负责无符号位全64位乘法.imull这个指令好像是负责乘法的指令,而且在之前的乘法并没有区分有符号和无符号,现在怎么又成了双胞胎了呢?

我们再上一张当中出现的指令时imull指令,当他操作双字的时候,也就是imull指令.不过不同的是,他的一般形式是imull S D,这里有两个操作数,它将计算S和D的乘积并截断为双字,然后存储在D当中.由于在截断时,无符号以及有符号的二进制序列是一样的,因此此处的乘法指令并不区分有符号和无符号.

本次我们讨论imull指令,则与上面的普通乘法指令稍有不同,他只有一个操作数,也就是说,他的一般形式为imull S,而另外一个操作数默认为%eax寄存器.最终的结果,会将高32位存入%edx寄存器,而低32位存入%eax寄存器.

试想一下,如果我们只取%eax寄存器当中的32位结果,那其实这里计算的结果就是S*%eax,此时imull S的作用与imull S D的作用是一样的,,只是目的操作数被固定为%eax罢了.

接下来我们看一个案例,我们去看指令imull $0x3的结果,我们假设此时%eax寄存器的值为0x82345600.也就是我们需要你计算0x3*0x82345600的值,这里我直接给出了两者相乘的十六进制表示,为0xFFFF FFFE 869D 0200.这个结果也是64位的,因此我们寄存器的前后状态为:

可以看出来,%eax保存着低32位的结果,单说这32位的话,他的有符号数值为-2036530688,正是我们直接计算0x3*0x82345600位截断后的有符号值,显然这个结果一出了.如果组合上高32位,则结果为-6331497984,将它加上或者取模(2的32次方)将得到我们32位的结果.这里的有符号乘法采取的是先符号位扩展被乘数,然后两者相乘,将结果再阶段为64位所得.

对于mull的单操作数指令来说,就很简单了,它采用的是无符号乘法,因此就和我们平时的十进制乘法类似可,只是同样的,他也会将结果的高32位存入%edx,将低32位存入%eax

cltd指令

这个指令相对来说很简单,就是简单的将%eax寄存器的值符号扩展32位到%edx寄存器,也就是说,如果%eax寄存器的二进制序列的最高位为0,则cltd指令就把%edx置为32个0,相反,如果%eax寄存器的二进制序列最高位为1,则cltd指令将会自从填充%edx寄存器为32个1.

idivl,divl指令

这两个指令玉前面的imull和mull类似,它也将计算结果粗放在两个寄存器当中,其中余数存放在%edx寄存器,商存放在%eax寄存器.如果你能了解前面说的imull和mull,那么这里的idivl和divl理解起来就会很简单.

举个例子,考虑指令idivl $0x3的结果,我们结社此时%eax寄存器的值为0x82345600.也就是数我们需要计算0x82345600/0x3的值,在这里我直接给出两数相除的16进制表示,商为0xD6117200.余数为0x0.因此我们寄存器的前后状态如下所示:

可以看出,在idivl这个指令执行的过程中,其实对被除数进行了符号扩展,类似于cltd指令,,或者有时也会将%eax移动到%edx,然后对%edx进行算术右移31位的运算.这两种方式的结果是一样的,都是将%eax符号扩展32位并存储在%edx当中.

小小的结一下

本次我们介绍了一下介个特殊的算术运算指令,其实这些指令的运算规则都是建立在二进制算术规则的基础上的,二进制算数规则就是这些指令的执行方式规定.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-18 10:53:20

特殊的算术操作指令详解的相关文章

迈向angularjs2系列(2):angular2组件和指令详解

<%= INIT %> 内容 一:angular2 helloworld! 为了简单快速的运行一个ng2的app,那么通过script引入预先编译好的angular2版本和页面的基本框架. index.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> &l

Git大法好——2.Git本地操作指令详解

Git大法好--2.Git本地操作指令详解 引言 上节给大家讲解了有关于Git的一些概念,Git的引入,Git的四个组成部分,Git文件的状态,以及 Git的下载安装:前面也讲过Git和SVN有个明显的差别就是,Git可以不需要网络就可以进行版本 控制,这是因为Git中每个电脑都拥有一个本地的版本库,而远程的仓库仅仅是作为我们交换修改 的一个工具!即使失去这个工具,我们也可以干活,只是交换修改不方便罢了,假如是SVN,远程 服务器挂了-所以,我们使用Git的时候大部分时间都是在进行Git的一些本

[转]JVM指令详解(上)

作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 本文主要记录一些JVM指令,便于记忆与查阅. 一.未归类系列A 此系列暂未归类. 指令码    助记符                            说明 0x00         nop                                什么都不做 0x01        aconst_null                   将null推送至栈顶 二.const系列 该系列命令主要

tar 指令详解

tar 解压缩命令 tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的参数是根据需要在压缩或解压档案时可选的. -z:有gzip属性的 -j:有bz2属性的 -Z:有compress属性的 -v:显示所有过程 -O:将文件解开到标准输出 下面的参数-f是必须的 -f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名. # ta

&lt;linux下sysctl指令详解&gt;

Sysctl指令是对系统核心参数的设置: 用法: -a 参数列出系统中所有核心设置 当然了这些核心的设置都是文件,存放于/proc/sys/net目录下. 举个有代表性的例子: net.ipv4.icmp_echo_ignore_all = 0      把所有的点改为 / 就可以了.   [[email protected] net]# net.ipv4.icmp_echo_ignore_all = 0 [[email protected] net]# cd ipv4/ [[email pro

16位汇编第六讲汇编指令详解第二讲

16位汇编第六讲汇编指令详解第二讲 1.比较指令 CMP指令 1.CMP指令是将目的操作数减去源操作数,按照定义相应的设置状态标志 2.CMP指令执行的功能与SUB指令(相减指令)一样,但是不同的是CMP指令之根据结果设置标志位 而不修改值 可以操作的指令格式 CMP reg,imm/reg/mem CMP mem,imm/reg 上面是CMP指令的语法,具体的也可以查询帮助文档,inter手册 inter手册查的办法 第一个框代表了CMP指令的所有语法 比如 reg,reg 表示可以比较寄存器

16位汇编第五讲各种指令详解第一讲

汇编指令详解 8080指令详解 1.8086系统下,Inter指令系统共有117条指令(看似很多,分一下类) 1.数据传送类指令(专门传送数据的) 2.算术运算类指令(加减乘除的运算的) 3.位操作类指令(或  异货 与 -.) 4.串操作类指令 (内存拷贝,内存连续地址拷贝的操作) 5.控制转移类指令(跳转,比如C语言的Goto) 6.处理机控制类指令(计算机的待机 ,重启 等等,让CPU待机睡眠的指令) 学习指令的注意事项 1.指令的功能,也就是这个指令可以实现什么操作.通常的话,指令就是指

Linux指令详解useradd groupadd passwd chpasswd chage 密码修改

创建用户.设置密码.修改用户.删除用户: useradd testuser 创建用户testuser passwd testuser 给创建的用户testuser设置密码 说明:新创建的用户会在/home下创建一个用户目录testuser usermod --help 修改用户这个命令的相关参数 userdel testuser 删除用户testuser rm -rf testuser 删除用户testuser所在目录 上面的几个命令只有root账号才可以使用,如果你不知道自己的系统上面的命令在

iret指令详解

在"实地址模式"中,IRET 指令执行到中断程序或过程的远返回.在执行此操作的过程中,处理器从堆栈将返回指令指针.返回代码段选择器以及 EFLAGS 映像分别弹入 EIP.CS 以及 EFLAGS 寄存器,然后恢复执行中断的程序或过程. 在"保护模式"中,IRET 指令的操作取决于以下因素:EFLAGS 寄存器中 NT(嵌套任务)与 VM 标志的设置,以及当前堆栈中存储的 EFLAGS 映像中的 VM 标志的设置.根据这些标志的设置,处理器执行以下类型的中断返回: