7.5  扩展加法和减法

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

7.5.1  ADC指令

ADC(AddWithCarry)指令把源操作数、目的操作数以及进位标志相加。指令格式与MOV指令是一样的:

ADC  reg ,reg

ADC  mem ,reg

ADC  reg ,mem

ADC  mem ,imm

ADC  reg ,imm

例如,下面的指令把两个8位整数相加(FFh+FFh),16位解雇01FEh被存放在DL:AL中:

mov  dl ,0

mov  al ,0FFh

add   al ,0FFh   ;AL = FE

adc   dl ,0      ;DL = 01

两个32位整数相加(FFFFFFFFh+FFFFFFFFh)相加,在EDX:EAX中存放64位的和0000001FFFFFFFEh:

mov  edx ,0

mov  eax ,0FFFFFFFFh

add   eax ,0FFFFFFFFh

adc   edx ,0


7.5.2  扩展加法的例子

下面的Extended_Add过程把两个任意相同尺寸的整数相加,程序使用一个循环把没对双字相加,保存进位标志,并是仅为标志参与后面的双字的假发运算:

下面摘自ExtAdd.asm的程序片段调用了Extended_Add过程,例子中传递的是两个64位整数。注意特别分配了额外的双字节以保存可能出现的进位值:

果真发生了进位,注意一个问题,就是比如op1 QWORD 0A2B2A40674981234h

eax  =  OFFSET op1

那么[eax] 是74981234h  而[eax+4]是0A2B2A406。一开始我在最后输出的时候没看懂,后台调试的时候想起来了。

 

7.5.3  SBB指令

SBB(subtract with borrow)指令从墓地操作数中减去源操作数和进位标志的值。指令允许你的操作与ADC是相同的。

下面的例子是执行64位的减法,把EDX:EAX设置为0000000100000000h并从中减去1,程序首先减去低32位值,进位标志将被设置,然后再减去高32位和进位标志值:

mov  edx ,1    ;高半部分

mov  eax ,0    ;低半部分

sub   eax , 1   ;减去1

sbb   edx ,0   ;减去1的高半部分(0)

EDX:EAX 中的64位差值是00000000FFFFFFFFh。

7.6  ACCII和未压缩十进制算术指令

到现在为止,本书讲述的整数算术指令都是处理二进制数值的,尽管CPU是以二进制算术方式进行运算的,但是也能处理ASCII十进制数串的算术运算。后者可以方便地有用户输出并在控制台窗口中显示,无需转换成二进制数值。假设程序需要用户输入两个数字并把他们相加,下面是一个输出样例,其中用书输入了3402和1256:

Enter first numbers:    3402

Enter second number:  1256

The sum is:           4658

在计算和显示数字的时候有两种选择:

1.把两个操作数转换成二进制数值并相加,然后把和从二进制数转换成ASCII码数字串的格式化后显示。

2.连续地把没对ASCII数字直接相加,这样就和是ASCII数字串,可以直接在屏幕上显示。

第二种选择要求在对ASCII数字相加后使用特殊指令来调整其和,指令集中有4条指令可以处理这一类的ASCII加法、减法、乘法和除法:

mov    ah ,0

mov    al ,’8’     ;AX = 0038h

add     al,’2’     ;AX = 006Ah

aaa              ;AX = 0100h(结果的ASCII码调整)

or      ax ,3030h ;AX = 3130h=’10’(转换成ACSCII码)

AAS AAM AAD也是如此。

7.7.1  DAA指令

DAA指令把ADD和ADC指令执行后AL中的二进制数转换成压缩的十进制数格式。

mov  al ,35h

add  al ,48h    ;AL = 7Dh

daa            ;AL = 83h(调整结果)

7.7.2  DAS指令

DAS(decimal adjust after subtraction)指令将SUB或SBB指令执行后AL中的二进制转换成压缩的十进制格式。

mov bl ,48h

mov al ,85h

sub al ,bl   ;AL = 3Dh

das       ;AL = 37h(调整结果)

7.8 本章小结

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

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

    第七章 整数算术指令 7.1 简介 每种汇编语言都有进行操作数移位的指令,移位和循环移位指令在控制硬件设备.加密数据,以及实现高速的图形操作时特别有用.本章讲述如何进行移位和循环移位操作以及如何使用移 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. Intel汇编语言程序设计学习-第三章 汇编语言基础-下

    3.4  定义数据 3.4.1  内部数据类型 MASM定义了多种内部数据类型,每种数据类型都描述了该模型的变量和表达式的取值集合.数据类型的基本特征是以数据位的数目量的大小:8,16,32,,48, ...

随机推荐

  1. LZZ高级程序语言设计之多重for循环

    public class Mq { public static void main(String args[]) { System.out.println("到底去还是不去呢?") ...

  2. 如何强制删除一个apk

    有些apk安装完后无法卸载,现在收集了一些方法,以及个人的一些手段. 1. 假设该app名为ketech,安装包名为ketech.apk. 2. 查看/data/app里面是否有名称包含ketech的 ...

  3. requirejs的用法

    requirejs的用法 2014年11月6日 17164次浏览 之前我的一片文章介绍过requirejs,具体地址是:http://www.haorooms.com/post/RequireJS_m ...

  4. python实现顺序表

    python实现顺序表可以有两中形式进行存储 列表 元组 其实简单来说,顺序表无非就是操作列表和元组的方法来对顺序表进行操作. 实例代码 7 class SqList: 8 def __init__( ...

  5. spring-boot记录sql探索

    目标记录每次请求内的http.es.mysql耗时,本篇讨论mysql部分 为什么说要探索,这不是很简单的事么?但是能满足以下几点么? 能记录limit等参数 能将参数和sql写一起,能直接使用 能记 ...

  6. 冒泡排序算法的实现(Java)

    什么是冒泡排序 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法.它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小.首字母从Z到A)错误就把他们交换 ...

  7. 攻防世界 reverse 进阶5-7

    5.re-for-50-plz-50  tu-ctf-2016 流程很简单,异或比较 1 x=list('cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ') 2 y=0x37 3 z= ...

  8. [go-linq]-Go的.NET LINQ式查询方法

    关于我 我的博客|文章首发 开发者的福音,go也支持linq了 坑爹的集合 go在进行集合操作时,有很不舒服的地方,起初我真的是无力吐槽,又苦于找不到一个好的第三方库,只能每次写着重复代码.举个栗子 ...

  9. 最短路径(Dijskra算法)

    声明:图片及内容基于:https://www.bilibili.com/video/BV16C4y1H7Zc?from=articleDetail 最短路径 Dijkstra算法 原理 数据结构 核心 ...

  10. [BFS]骑士旅行

    骑士旅行 Description 在一个n m 格子的棋盘上,有一只国际象棋的骑士在棋盘的左下角 (1;1)(如图1),骑士只能根据象棋的规则进行移动,要么横向跳动一格纵向跳动两格,要么纵向跳动一格横 ...