汇编语言 数字

  • 数字

    数值数据通常用二进制表示。算术指令对二进制数据进行操作。当数字显示在屏幕上或从键盘输入时,它们是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_num:  
       mov  al, [num1 + esi]
       adc  al, [num2 + esi]
       aaa
       pushf
       or   al, 30h
       popf
            
       mov  [sum + esi], al
       dec  esi
       num  add_num
            
       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