Assembly 数字 - Assembly汇编

数值数据普遍表示二进制系统。算术指令的操作上的二进制数据。当数字显示在屏幕上,或从键盘输入,它们是ASCII形式。

到目前为止,我们已经转换成ASCII形式输入数据进行算术运算的二进制结果转换回二进制。下面的代码显示:

section    .text
    global _start         ;must be declared for using gcc
_start:    ;tell linker entry yiibai
    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,32H是ASCII值1 ASCII值2,依此类推。有以下四个指令处理数字的ASCII表示:

  • AAA - ASCII Adjust After Addition

  • AAS - ASCII Adjust After Subtraction

  • AAM - ASCII Adjust After Multiplication

  • AAD - ASCII Adjust Before Division

这些指令不采取任何操作数,并承担所需的操作数是在AL寄存器中。

下面的示例使用AAS指令来说明这个概念:

section    .text
    global _start         ;must be declared for using gcc
_start:    ;tell linker entry yiibai
    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表示

在压缩BCD表示,每个字节的存储的二进制相当于十进制数字。例如,被存储为数字1234:

01    02    03    04H

有两种处理这些数字指令:

  • AAM - 乘法后ASCII调整

  • AAD - ASCII除法前调整

四个ASCII调整指令,AAA,AAS,AAM和AAD也可以用压缩BCD表示。压缩BCD码表示,每个使用四位数字存储。两位十进制数被打包成一个字节。例如,被存储为数字1234:

12    34H

有两种处理这些数字指令:

  • DAA - Decimal Adjust After Addition

  • DAS - decimal Adjust After Subtraction

乘法和除法包装BCD表示不支持。

例子:

下面的程序增加了两个5位数的十进制数和显示的总和。它使用上述的概念:

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

_start:    ;tell linker entry yiibai

    mov     esi, 4  ;yiibaiing 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