数字(Numbers)
优质
小牛编辑
132浏览
2023-12-01
数值数据通常以二元系统表示。 算术指令对二进制数据进行操作。 当数字显示在屏幕上或从键盘输入时,它们是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表示中不支持乘法和除法。
例子 (Example)
以下程序将两个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