深入理解计算机系统(3.5)------特殊的算术操作指令

  在上一篇博客 算术和逻辑操作 我们介绍了如下图几种常用的算术逻辑指令,但是大家发现没,这几种指令如果在 IA32 上只能操作32位寄存器,比如我用乘法指令IMUL得出的结果超过了32位,那就会产生结果溢出,那应该怎么办呢?

1、特殊的算术操作指令指令

  如上图,上面的几个指令支持有符号和无符号的全64位乘积以及整数除法,但是需要注意的是,存储结果的寄存器固定死了,是一对寄存器%edx(高32位)和%eax(低32位)组成的 64 位的四字。

2、imull 和 mull 指令

  对于 imull 指令,上一章我们在讲算术和逻辑操作指令的时候,讲过这个指令,这是一个乘法指令,指令形式是 imull S D,这里有两个操作数,它将计算S和D的乘积并截断为双字,然后存储在D当中。由于在截断时,无符号以及有符号的二进制序列是一样的,因此此处的乘法指令并不区分有符号和无符号。

  但是对于本章的 imull 指令,它和前面的所表示的乘法指令有所不同,这里只有一个操作数,如上图,它的指令形式是 imull S。但是实际上它还有一个默认的操作数——寄存器%eax,这两者相乘,最终的结果是将高32位存入%edx 寄存器,低 32 位存入%eax 寄存器。

  如果我们只取低 32 位的结果,那么这里指令的意思和上篇博客所讲的乘法指令意思是一样的了,imull S D,只不过这里的D是寄存器 %eax。

  这里我们可以看一个实例:imull $0x3,我们假设此时%eax寄存器的值为0x82345600。也就是我们需要计算0x3*0x82345600的值,这里直接给出两者相乘的16进制表示,为0xFFFF FFFE 869D 0200。这个结果为64位的,因此我们寄存器的前后状态如下所示。

  本实例引用:http://www.cnblogs.com/zuoxiaolong/p/computer17.html

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

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

  所以虽然 imull 可以用于两种不同的乘法操作,但是汇编器能够通过计算操作数的数据,分辨出想用哪条指令。

3、cltd 指令

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

4、idivl、divl指令

  这两个指令分别是有符号除法和无符号除法指令,有符号除法指令 idivl 将寄存器 %edx(高32位)和 %eax(低32位)中的64位数作为被除数,而除数作为指令的操作数给出。指令将商存储在寄存器 %eax 中,将余数存储在寄存器 %edx 中。

  比如指令idivl $0x3的结果,我们假设此时%eax寄存器的值为0x82345600。也就是我们需要计算0x82345600/0x3的值,这里直接给出两者相除的16进制表示,商为0xD6117200,余数为0x0。因此我们寄存器的前后状态如下所示。

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏青枫的专栏

c语言基础学习06_函数

============================================================================= 涉及...

772
来自专栏程序员互动联盟

【编程基础】Java的八种基本数据类型

程序=数据+算法,也就是说程序就是你编写算法操作数据。Java是一种强类型语言,也就是说每一个变量都必须是某种类型的变量。在Java中数据类型分为基本数据类型和...

3438
来自专栏我和PYTHON有个约会

08.程序编程基础2~基本数据类型

布尔类型,一种特殊的数据类型,在python中可以取值为True或者False,用于表示只有两种结果的情况

683
来自专栏nummy

numpy入门

numpy中最主要的对象是同质数组array,也就是说数组中的元素类型都是一样的。数组的维度也称之为axis,axis的的个数称之为秩rank。

702
来自专栏烂笔头

Python标准库笔记(10) — itertools模块

2326
来自专栏十月梦想

JavaScript数组对象

万能操作 数组.splice(开始位置,数量,操作),操作后原数组的内容改变第一个参数是指定从几号位置开始删除或添加  第二个参数是指定删除几个元素

823
来自专栏Java帮帮-微信公众号-技术文章全总结

Java基础-Java基础-02总结关键字,标识符,注释,常量进制,变量数据类型

首先原谅小编的过错,昨天第二篇文章标题是: 程序员:为什么选择Java? ? 1:关键字(掌握) (1)被Java语言赋予特定含义的单词 (2)特点: 全...

2325
来自专栏吾爱乐享

java之学习Random类的概述和注意事项

813
来自专栏Java架构师历程

基本数据类型及引用数据类型

byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0

793
来自专栏landv

java基本数据类型

1343

扫码关注云+社区