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