📜  装配体-数字

📅  最后修改于: 2020-11-05 05:08:12             🧑  作者: Mango


数值数据通常用二进制表示。算术指令对二进制数据进行操作。当数字显示在屏幕上或从键盘输入时,它们是ASCII形式。

到目前为止,我们已经将该输入数据以ASCII形式转换为二进制以进行算术计算,并将结果转换回二进制。以下代码显示了这一点-

section    .text
   global _start        ;must be declared for using gcc
    
_start:                    ;tell linker entry point
   mov    eax,'3'
   sub     eax, '0'
    
   mov     ebx, '4'
   sub     ebx, '0'
   add     eax, ebx
   add    eax, '0'
    
   mov     [sum], eax
   mov    ecx,msg    
   mov    edx, len
   mov    ebx,1             ;file descriptor (stdout)
   mov    eax,4             ;system call number (sys_write)
   int    0x80             ;call kernel
    
   mov    ecx,sum
   mov    edx, 1
   mov    ebx,1             ;file descriptor (stdout)
   mov    eax,4             ;system call number (sys_write)
   int    0x80             ;call kernel
    
   mov    eax,1             ;system call number (sys_exit)
   int    0x80             ;call kernel
    
section .data
msg db "The sum is:", 0xA,0xD 
len equ $ - msg   
segment .bss
sum resb 1

编译并执行上述代码后,将产生以下结果-

The sum is:
7

但是,此类转换会产生开销,并且汇编语言编程允许以更有效的方式以二进制形式处理数字。小数可以两种形式表示-

  • ASCII形式
  • BCD或二进制编码的十进制格式

ASCII表示

在ASCII表示中,十进制数字存储为ASCII字符字符串。例如,十进制值1234存储为-

31    32    33    34H

其中,31H是1的ASCII值,32H是2的ASCII值,依此类推。有四个指令以ASCII表示形式处理数字-

  • AAA-加法后ASCII调整

  • AAS-减法后的ASCII调整

  • AAM-乘法后ASCII调整

  • AAD-除法前ASCII调整

这些指令不使用任何操作数,并假定所需的操作数位于AL寄存器中。

以下示例使用AAS指令演示概念-

section    .text
   global _start        ;must be declared for using gcc
    
_start:                    ;tell linker entry point
   sub     ah, ah
   mov     al, '9'
   sub     al, '3'
   aas
   or      al, 30h
   mov     [res], ax
    
   mov    edx,len            ;message length
   mov    ecx,msg            ;message to write
   mov    ebx,1            ;file descriptor (stdout)
   mov    eax,4            ;system call number (sys_write)
   int    0x80            ;call kernel
    
   mov    edx,1            ;message length
   mov    ecx,res            ;message to write
   mov    ebx,1            ;file descriptor (stdout)
   mov    eax,4            ;system call number (sys_write)
   int    0x80            ;call kernel
    
   mov    eax,1            ;system call number (sys_exit)
   int    0x80            ;call kernel
    
section    .data
msg db 'The Result is:',0xa    
len equ $ - msg            
section .bss
res resb 1  

编译并执行上述代码后,将产生以下结果-

The Result is:
6

BCD表示

BCD表示有两种类型-

  • 未包装的BCD表示
  • 打包的BCD表示

在未压缩的BCD表示形式中,每个字节都存储一个十进制数字的二进制等效项。例如,数字1234存储为-

01    02    03    04H

有两个指令来处理这些数字-

  • AAM-乘法后ASCII调整

  • AAD-除法前ASCII调整

四个ASCII调整指令AAA,AAS,AAM和AAD也可以与未打包的BCD表示一起使用。在打包的BCD表示中,每个数字使用四位存储。两个十进制数字打包成一个字节。例如,数字1234存储为-

12    34H

有两个指令来处理这些数字-

  • DAA-加法后的十进制调整

  • DAS-减后小数调整

打包的BCD表示形式不支持乘法和除法。

以下程序将两个5位十进制数字加起来并显示总和。它使用以上概念-

section    .text
   global _start        ;must be declared for using gcc

_start:                    ;tell linker entry point

   mov     esi, 4       ;pointing to the rightmost digit
   mov     ecx, 5       ;num of digits
   clc
add_loop:  
   mov     al, [num1 + esi]
   adc     al, [num2 + esi]
   aaa
   pushf
   or     al, 30h
   popf
    
   mov    [sum + esi], al
   dec    esi
   loop    add_loop
    
   mov    edx,len            ;message length
   mov    ecx,msg            ;message to write
   mov    ebx,1            ;file descriptor (stdout)
   mov    eax,4            ;system call number (sys_write)
   int    0x80            ;call kernel
    
   mov    edx,5            ;message length
   mov    ecx,sum            ;message to write
   mov    ebx,1            ;file descriptor (stdout)
   mov    eax,4            ;system call number (sys_write)
   int    0x80            ;call kernel
    
   mov    eax,1            ;system call number (sys_exit)
   int    0x80            ;call kernel

section    .data
msg db 'The Sum is:',0xa    
len equ $ - msg            
num1 db '12345'
num2 db '23456'
sum db '     '

编译并执行上述代码后,将产生以下结果-

The Sum is:
35801