📅  最后修改于: 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表示中,十进制数字存储为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表示形式中,每个字节都存储一个十进制数字的二进制等效项。例如,数字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