`
qdujunjie
  • 浏览: 110359 次
  • 性别: Icon_minigender_1
  • 来自: Mars
社区版块
存档分类
最新评论

汇编语言AAA指令多字节加法代码分析(5)

阅读更多

 

来自于《Intel汇编语言程序设计》(第五版)第七章的代码,使用AAA( ASCII adjust after addition )指令来调整ASCII相加之后的结果。源代码如下:

 

TITLE ASCII Addition                                                    (ASCII_add.asm)

 

; Perform ASCII arithmetic on strings having

; an implied fixed decimal point

 

INCLUDE Irvine32.inc

 

DECIMAL_OFFSET = 5                                                 ; offset from right of string

 

.data

decimal_one BYTE "100123456789765"                     ; 1001234567.89765

decimal_two BYTE "900402076502015"                     ; 9004020765.02015

sum BYTE (SIZEOF decimal_one + 1) DUP(0),0

 

.code

main PROC

; start at the last digit position.

           mov esi, SIZEOF decimal_one - 1

           mov edi,SIZEOF decimal_one

           mov ecx,SIZEOF decimal_one

           mov bh,0                                                          ; set carry value to zero

L1:

           mov ah,0                                                          ; clear AH before addition

           mov al,decimal_one[esi]                                   ; get the first digit

           add al,bh                                                          ; add the previous carry

           aaa                                                                   ; adjust the sum ( AH = carry )

           mov bh,ah                                                         ; save the carry in carry1

           or bh,30h                                                          ; convert it to ASCII

           add al,decimal_two[esi]                                   ; add the second digit

           aaa                                                                   ; adjust the sum ( AH = carry )

           or bh,ah                                                           ; OR the carry with carry1

           or bh,30h                                                          ; convert it to ASCII

           or al,30h                                                           ; convert AL back to ASCII

           mov sum[edi],al                                                ; save it in the sum

           dec esi                                                              ; back up one digit

           dec edi

           loop L1

           mov sum[edi],bh;                                             ; save last carry digit

; Display the sum as a string.

           mov edx,OFFSET sum

           call WriteString

           call crlf

           exit

main ENDP

END main

 

 

下面开始逐句分析。

 

 

decimal_one BYTE "100123456789765"                     ; 1001234567.89765

decimal_one BYTE "900402076502015"                     ; 9004020765.02015

sum BYTE (SIZEOF decimal_one + 1) DUP(0),0

 

首先定义了两个数字字符串,用来隐含进行小数点的加法。随后定义了一个放置和的sum变量,这个变量多了一位来放置进位。

 

 

然后再来看代码段:

 

 

           mov esi, SIZEOF decimal_one - 1

           mov edi,SIZEOF decimal_one

           mov ecx,SIZEOF decimal_one

           mov bh,0                                                          ; set carry value to zero

 

首先,为循环游标 esi 赋值为字符串的最后一个位置,即SIZEOF decimal_one - 1,此时即指向decimal_one的最后一位数字"5" 。 然后是sum的游标edi,为其赋值为SIZEOF decimal_one(因为我们这里比decimal_one的长度多了一位,用来存储进位),还有循环数ecx,赋值为decimal_one的长度。

 

最后把进位值bh设置为零。

 

 

 

然后让我们看一下接下来的代码:

 

 

 

L1:

           mov ah,0                                                          ; 在进行AAA指令之前,一定要清空ah,否则会影响AAA指令结果

           mov al,decimal_one[esi]                                   ; 得到decimal_one的esi位置的数字

           add al,bh                                                          ; 将之前的进位值与al相加(例如,第一次相加时没有进位)

           aaa                                                                   ; 使用aaa调整相加结果,会将进位值保存到ah中

           mov bh,ah                                                         ; 将进位值保存到bh中

           or bh,30h                                                          ; 将此时的结果转化成ASCII码

           add al,decimal_two[esi]                                   ; 再与decimal_two的第esi位数字相加,保存到al中

           aaa                                                                   ; 调整加法结果,进位将会保存到AH中

           or bh,ah                                                           ; 将现在的进位进行或操作(不太明白为什么)

           or bh,30h                                                          ; 将进位值转化为ASCII码

           or al,30h                                                           ; 将AL中的值转化为ASCII码

           mov sum[edi],al                                                ; 将计算完的此位值赋值到sum相应位

           dec esi                                                              ; 向前移一位,取得下一个相加数的游标位置

           dec edi                                                              ; 向前移一位,取得下一个相加数的游标位置

           loop L1                                                              ; 执行下次循环

           mov sum[edi],bh;                                             ; 计算完成之后,将最后一次的进位加到sum的第edi位置

 

; Display the sum as a string.

           mov edx,OFFSET sum                                       ; 将sum的偏移地址赋值到edx中

           call WriteString                                                 ; 在屏幕上显示此时edx的值,也就是sum的结果

           call crlf                                                              ; 光标移动到下一行开头

           exit                                                                   ; 退出(Irvine32中的函数)

 

 

到这里,程序分析便结束了,程序的结果将为:

 

1000525533291780

 

结果共为16位(原两个相加数为15位),并且隐含了小数点。

 

 

补充:

因为 ASCII 码的十进制数中的最高位总是0011b,所以才会进行 or bh,30h 的操作;其中未将ASCII码的十进制数的高四位设置为0011b的为未压缩格式,设置之后的才为ASCII格式,示例如下:

 

ASCII格式:    33 34 30 32

未压缩格式:    03 04 00 02

 

 

0
0
分享到:
评论
1 楼 a376730551 2013-01-14  
红色部分表示  把进位值传递给bh

相关推荐

    汇编语言程序指令大全

    汇编语言程序指令大全 汇编语言是低级programming语言,它直接使用机器语言指令对计算机进行控制和操作。该语言程序指令大全涵盖了数据传输指令、算术运算指令、逻辑运算指令、转移指令等多种类型的指令。 一、...

    汇编语言指令大全_详解版

    当进行多字节加法时,可以使用ADC来处理进位。 - ADD(Addition)指令用于两个操作数的相加。它支持无符号和有符号数的加法,并影响标志寄存器中的各个标志位。 三、逻辑与指令 AND指令是逻辑运算指令之一,它按照...

    汇编语言指令大全.doc

    本文将深入探讨几种重要的汇编语言指令,包括AAA、AAD、AAM、AAS、ADC、ADD以及AND,这些都是在汇编语言编程中常用的指令。 **AAA(ASCII Adjust for Addition):**该指令用于调整组合的十进制加法运算结果,确保...

    汇编语言指令大全_详解版_

    汇编语言是面向机器的语言,直接对应着机器代码,它是一种低级语言,其指令的执行效率通常高于高级语言。在汇编语言中,指令的种类非常丰富,这些指令可以细分为数据传送指令、算术运算指令、逻辑运算指令、控制转移...

    汇编语言指令集

    ### 汇编语言指令集解析 #### 一、算术与逻辑操作指令 汇编语言中的算术和逻辑操作指令是程序中最基础且最常用的一类指令,用于执行基本的数学运算和位操作。 - **ADC(带进位加法)**:此指令将两个操作数相加,...

    IBM-PC汇编语言指令集

    ### IBM-PC汇编语言指令集详解 #### 汇编语言与指令集概述 IBM-PC汇编语言是用于编程的一种低级语言,它直接对应于计算机的机器指令,通常用于编写对性能要求极高的程序或进行底层硬件操作。在IBM-PC体系结构中,...

    DSP C6000系列 常用汇编指令大全

    该文档包含了DSP C6000系列芯片的全部汇编指令,涵盖了数据传输、输入输出端口传送、目的地址传送、标志传送、算术运算、逻辑运算等多个方面。 一、数据传输指令 数据传输指令用于在存贮器和寄存器、寄存器和输入...

    汇编语言指令大全(非常有用)

    汇编语言指令大全 汇编语言是计算机系统的基础语言,它直接操作计算机硬件资源,具有很高的执行效率和灵活性。汇编语言的指令集是汇编语言的核心组成部分,它定义了汇编语言的语法和语义。 通用数据传送指令 ...

    汇编语言指令大全

    ### 汇编语言指令详解 #### AAA:未组合的十进制加法调整指令 - **指令格式**:AAA - **功能描述**:在进行两个组合的十进制数(位于AL寄存器中)相加之后,对结果进行调整,使其成为未组合的十进制数,并将调整后...

    汇编指令表

    ADD 指令可以执行加法,ADC 指令可以执行带进位加法,INC 指令可以增加 1,AAA 指令可以执行加法的 ASCII 码调整,DAA 指令可以执行加法的十进制调整。SUB 指令可以执行减法,SBB 指令可以执行带借位减法,DEC 指令...

    微型计算机原理和汇编语言 8086/8088 汇编语言指令表

    该指令通常用于多字节加法运算。 3. **INC (Increment)**: `INC opr`指令将操作数`opr`加1,并将结果送回`opr`中。这是一个简单的增量操作。 4. **SUB (Subtraction)**: `SUB dst, src`指令从`dst`减去`src`,并将...

    汇编语言常用指令[归类].pdf

    由于原始文件内容存在一些OCR扫描错误,具体代码的解释可能不完全准确,但从给出的内容可以看出,文档试图系统地对汇编语言的常用指令进行分类和说明。这有助于读者更好地理解每条指令的功能和应用场景,从而更加...

    汇编语言指令 掌握良好 开头

    ### 汇编语言指令详解 #### 一、数据移动指令 **MOV**:移动指令,用于将一个值从一个位置复制到另一个位置。例如,`MOV AX, BX` 将寄存器 BX 的值复制到寄存器 AX 中。 **PUSH**:压栈指令,用于将指定的数据压...

    汇编指令(chm格式)

    AAA 加法的ASCII码调整. DAA 加法的十进制调整. SUB 减法. SBB 带借位减法. DEC 减 1. NEC 求反(以 0 减之). CMP 比较.(两操作数作减法,仅修改标志位,不回送结果). AAS 减法的ASCII码调整. DAS ...

    汇编语言指令集 微型计算机原理与接口技术

    本资源摘要信息主要介绍了汇编语言指令集的知识点,包括数据传输指令、输入输出端口传送指令、目的地址传送指令、标志传送指令、算术运算指令、逻辑运算指令等内容。 一、数据传输指令 数据传输指令用于在存贮器和...

    常用汇编指令(常用汇编指令)

    汇编语言是基于 CPU 指令集的低级编程语言,它使用符号表示来表示机器语言指令,从而使得编程更加灵活和高效。下面是常用的汇编指令分类: 1. 通用数据传送指令 MOV:传送字或字节 MOVSX:先符号扩展,再传送 ...

    X86汇编语言指令集.doc

    ### X86汇编语言指令集解析 #### AAA(ASCII Adjust for Addition)—— 未组合的十进制加法调整指令 **指令说明**: - **格式**:AAA - **功能**:此指令用于对两个组合的十进制数(位于 AL 寄存器中)相加的结果...

Global site tag (gtag.js) - Google Analytics