第七章 整数算术指令

7.1 简介

每种汇编语言都有进行操作数移位的指令,移位和循环移位指令在控制硬件设备、加密数据,以及实现高速的图形操作时特别有用。本章讲述如何进行移位和循环移位操作以及如何使用移位操作进行高效的乘法和出发运算。

接下来,我们将探究IA-32指令集中的乘法和出发指令,Intel根据运算是有符号还是无符号的对乘法和出发进行分类。本章还讲述如何把C++中的数学表达式翻译成汇编语言。编译器把符合表达式分解翻译成一系列机器指令,模拟编译器有助于理解其工作机制,同时也有助于更好地对汇编语言代码进行手工优化。通过本章的学习,读者对操作符优先级以及寄存器的优化(在机器层)的机制将有更深入的理解。

是否思考过计算机是如何加减多字整数?本章中讲述的ADC(带进位加)指令和SBB(带进位减)指令是的处理任意大小的整数更容易一些。在本章最后,将讲述Intel的一些专门处理压缩十进制整数数字字符串的算术指令。

7.2  移位和循环移位指令

和第6章介绍的位操作指令一样,移位指令也是最具汇编语言特性的指令。移位的含义是在操作数内向左或者向右移动数据位,Intel提供了多种移位指令,表中所有的移位指令都影响溢出标志和进位标志。

7.2.1  逻辑移位和算术移位

对于一个数字来说有两种最进本的移位操作。第一种为逻辑移位,即以0填充最后移出的位。在下图中,一个逻辑右移移位,请注意位7被赋值0。

假设二进制值11001111向右移动一位,那么得到0110111,最低位数据移入进位标志。

另一种移位类型成为算术移位,最后移出去的位用数字原来的符号位填充。

例如,二进制11001111的符号位是1,当算术右移一位的时候,就变成了11100111。

7.2.2  SHL指令

SHL指令对目标的操作数进行逻辑左移操作,最低位以0填充,溢出的最高位放在进位标志(CF),原来进位标志中的值将丢失。

二进制11001111左移移位就变成了10011110。

SHL指令的第一个操作数是目的操作数,第二个操作数是移位的位数:

SHL 目的操作数,移位位数

SHL指令允许使用下面的操作数类型:

SHL reg ,imm8

SHL mem ,imm8

SHL reg ,CL

SHL mem ,CL

Intel8086/8088处理器要求imm8必须等于1,从80286及以上的处理器开始,

imm8可以是0~255之间的整数。在任何Intel处理器上,都可以使用CL存放移位位数。这里列出的格式也适用于SHR
SAL SAR ROR ROL ROC和RCL指令。

例子:在下面的指令中,BL被左移一位。最高位被复制到进位标志中,最低位被清零。

mov bl ,8fh

shl bl ,1  CF,BL = 1,00011110b

多次移位:一个值多次左移试时,进位标志中的值是最后移出最高有效位(MSB)的数据位。在下面的例子中,进位标志的值是位6(0)而非位7的值:

mov al ,10000000b

shl  al ,2 ;CF = 0

右移也遵循同样规则。

快速乘法:使用SHL指令可以进行2的次幂的高速乘法操作。任何操作数左移n位就相当于乘以2的n次方。

7.2.3  SHR指令

SHR指令是逻辑右移,和逻辑左移格式什么完全一样。这里不再介绍。

7.2.4  SAL和SAR指令

SAL指令与SHL指令等价(这句话我纠结了好久,上面明明说算术移位是符号位填充,所以我会认为11110000算术左移之后是11100001结果却是11100000果真和SAL一样)。SAR指令对目的操作数执行算是右移操作:

SAR,SHR指令的格式与SHL,SHR指令的格式相同,移位动作可以根据第二个操作数中的计数进行重复:

SAR 目的操作数,移位位数

下面的例子显示了SAR复制符号位的情况,AL中的值在右移操作的前后都是负数:

mov  al ,0f0h   ;al = 11110000b (-16)

sar   al ,1      ;al = 11111000b(-8) CF = 0

有符号数的除法:使用SAR指令可以对有符号数进行除以我的次幂的快速操作。

mov  dl ,-128   ;dl = 10000000b    -128

sar   dl ,3      ;dl = 11110000b    -16

符号扩展AX至EAX:
先左移EAX16位,然后再算术右移EAX16位;

mov ax ,-128    ;EAX = ????FF80h

shl eax ,16      ;EAX = FF800000h

sar eax ,16      ;EAX = FFFFFF80h

7.2.5  ROL指令

ROL指令在向左一位后,把最高位同时复制到进位标志和最低位中,其指令格式与SHL指令相同:

7.2.6  ROR指令

循环右移,不解释了。

7.2.7  RCL和RCR指令

RCL指令在每位左移一位后,把进位标志复制到最低有效位中,把最低有效位复制到进位标志中。

如果把进位标志想象成一个填充到数字末尾的额外位的话,RCL指令就变成了一条简单的循环左移指令。在下例中,CLC指令清楚了进位标志,第一条RCL指令把BL的最高位送至进位标志,然后把其他位左移一位,第二条RCL指令把进位标志移入最低位,并把其他所有位左移:

clc            ;CF = 0

mov  bl ,88h   ;CF,BL = 0 ,10001000b

rcl   bl ,1      ;CF,BL =1,00010000b

rcl   bl,1      ;CF,BL =0,00100001b

从进位标志中恢复一个位:RCL指令可以回复以前送入进位标志中的数据位。下面的例子把testval的最低位送入进位标志已进行检查,如果testval最低位是1,则发生跳转,如果最低位是0,RCL指令把数字回复成原值:

.data

testval  BYTE 01101010b

.code

shr  testval ,1

jc   exit

rcl  testval ,1

RCR一样,只不过是右移 就不说了。

7.2.8  符号溢出

在使用移位和循环移位指令对一个有符号整数移位一位后得到的值如果超出了该操作数表示的有符号的范围,那么溢出标志就会置位。换句话说,在进行移位操作后数字的符号位变反时,溢出标志置位。

mov al ,+127   ;AL = 01111111b

rol  al ,1      ;OF = 1 ,AL = 11111110b

如果移位或循环移位的移位位数大于1,溢出标志值无定义。

7.2.9  SHLD/SHRD指令

SHLD和SHRD指令是从Intel386处理器开始引入的。SHLD指令把目的操作数左移指定的位数,左移出来的位用源操作数的高位来填充。指定对源操作数没有任何影响,但是符号标志、零标志、辅助进位标志。奇偶标志和进位标志都受影响。

SHLD 目的才作数,源操作数,移位位数

Intel汇编程序设计-整数算术指令(上)的更多相关文章

  1. Intel汇编程序设计-整数算术指令(下)

    7.5  扩展加法和减法 扩展精度的假发和减法是指任意尺寸大小数字的加法和减法.例如要求你写一个C++程序,把两个1024位的整数相加,解决方案可不是那么简单!但在汇编语言中,ADC(带进位加)指令和 ...

  2. Intel汇编程序设计-整数算术指令(中)

    7.3  移位和循环移位的应用 7.3.1  多双字移位 要对扩展精度整数(长整数)进行移位操作,可把它划分为字节数组.字数组或双字数组,然后再对该数组进行移位操作.在内存中存储数字时通常采用的方式是 ...

  3. Intel汇编程序设计-高级过程(上)

    第八章 高级过程 8.1 简介 本章主要讲: 堆栈框架 变量作用域和生存期 对战参数的类型 通过传递值或者传递引用来传递参数 在堆栈上创建和初始化局部变量 递归 编写多模块程序 内存模型和语言关键字 ...

  4. 《Intel汇编第5版》 Intel CPU小端序

    一.MASM汇编器中的数据类型 二.Intel汇编中的立即数类型 三.定义有符号和无符号整数 四.小端序 内存中数据按照字节存储,一个4个字节无符号整数,其高位存储在低地址上,低位存储在高地址上. 比 ...

  5. Linux下AT&T汇编语法格式与Intel汇编语法格式异同

    由于绝大多数的国内程序员以前只接触过Intel格式的汇编语言,很少或几乎没有接触过AT&T汇编语言,虽然这些汇编代码都是Intel风格的.但在Unix和Linux系统中,更多采用的还是AT&a ...

  6. AT&T 和 Intel 汇编语法的主要区别

    转自AT&T 和 Intel 汇编语法的主要区别 作为一个爱折腾的大好青年,补番之余还要补一些 Linux 下的基础,比如 GDB 的正确使用方法.但无论是看 gdb 还是 gcc -S 里的 ...

  7. ARM学习笔记11——GNU ARM汇编程序设计

    GNU ARM汇编程序设计中,每行的语法格式如下: [<label>:] [<instruction | directive | pseudo-instruction>] @c ...

  8. 《Intel汇编第5版》 汇编减法程序

    第一步: 安装虚拟机32位XP系统 + RadAsm软件 第二步:    下载<Intel汇编语言程序设计第5版>中相关的源代码以及库文件           http://kipirvi ...

  9. 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)

    2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...

随机推荐

  1. Linux下制作Windows启动U盘的工具

    Linux下制作Windows启动U盘的工具 很多人说Linux下制作Windwos启动盘要用GRUB4DOS建立引导,其实不用,有专门的工具的,就像Windows下有Rufus制作Linux启动U盘 ...

  2. @MockBean 注解后 bean成员对象为 null?

    笔者在写自测的时候遇到的问题: 我想模拟一个Bean,并在之后使用Mockito打桩,于是使用了 @MockBean 注解(spring集成mockito的产物),但代码编写好了后启动测试却报Null ...

  3. Apache配置 8.配置防盗链

    (1)介绍 防盗链,通俗讲,就是不让别人盗用你网站上的资源.这个资源,通常指的是图片.视频.歌曲.文档等. (2)配置 配置防盗链先编辑主机配置文件: #vim /usr/local/apache2. ...

  4. GTID介绍

    从MySQL5.6开始增加GTID这个特性,Global Transaction ID,全局事务ID,用来强化主从数据库的一致性,故障恢复,以及容错能力,来替代传统的人工的主从复制: 有了GTID,在 ...

  5. go中sync.Mutex源码解读

    互斥锁 前言 什么是sync.Mutex 分析下源码 Lock 位运算 Unlock 总结 参考 互斥锁 前言 本次的代码是基于go version go1.13.15 darwin/amd64 什么 ...

  6. 阿里二面:什么是mmap?

    平时在面试中你肯定会经常碰见的问题就是:RocketMQ为什么快?Kafka为什么快?什么是mmap? 这一类的问题都逃不过的一个点就是零拷贝,虽然还有一些其他的原因,但是今天我们的话题主要就是零拷贝 ...

  7. C#上机实验(三)

    源码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespac ...

  8. Web实验报告

  9. Android Studio 之 Button(圆角,描边,按压效果)

    •普通Button <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns: ...

  10. [Fundamental of Power Electronics]-PART I-4.开关实现-0 序

    4 开关实现 在前面的章节中我们已经看到,可以使用晶体管,二极管来作为Buck,Boost和其他一些DC-DC变换器的开关元件.也许有人会想为什么会这样,以及通常如何实现半导体的开关.这些都是值得被提 ...