汇编语言 数字
数值数据通常用二进制表示。算术指令对二进制数据进行操作。当数字显示在屏幕上或从键盘输入时,它们是 ASCII 形式。到目前为止,我们已经将该输入数据以 ASCII 形式转换为二进制以进行算术计算,并将结果转换回二进制。
下面看一个实例:
section .text
global _start ;必须声明 gcc
_start: ;告诉链接器入口点
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 ;文件描述 (stdout)
mov eax,4 ;系统调用号 (sys_write)
int 0x80 ;调用内核
mov ecx,sum
mov edx, 1
mov ebx,1 ;文件描述 (stdout)
mov eax,4 ;系统调用号 (sys_write)
int 0x80 ;调用内核
mov eax,1 ;系统调用号 (sys_exit)
int 0x80 ;调用内核
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 存储为:
31323334H
其中,31H 是 1 的 ASCII 值,32H 是 2 的 ASCII 值,依此类推。
有 4 种指令用于处理 ASCII 表示形式的数字-
AAA
- 加法后 ASCII 调整AAS
- 减法后的 ASCII 调整AAM
- 乘法后 ASCII 调整AAD
- 除法前 ASCII 调整
这些指令不使用任何操作数,并假定所需的操作数位于 AL 寄存器中。
比如下面的实例:
section .text
global _start ;必须声明 gcc
_start: ;告诉链接器入口点
sub ah, ah
mov al, '9'
sub al, '3'
aas
or al, 30h
mov [res], ax
mov edx,len ;消息长度
mov ecx,msg ;消息
mov ebx,1 ;文件描述 (stdout)
mov eax,4 ;系统调用号 (sys_write)
int 0x80 ;调用内核
mov edx,1 ;消息长度
mov ecx,res ;消息
mov ebx,1 ;文件描述 (stdout)
mov eax,4 ;系统调用号 (sys_write)
int 0x80 ;调用内核
mov eax,1 ;系统调用号 (sys_exit)
int 0x80 ;调用内核
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 存储为:
1234H
有两种指令来处理这些数字:
DAA
- 加法后的十进制调整DAS
- 减后的十进制调整
打包的 BCD 表示形式不支持乘法和除法。
实例
以下程序将两个 5 位十进制数字加起来并显示总和。
section .text
global _start ;必须声明才能使用 gcc
_start: ;告诉链接器入口点
mov esi, 4 ;指向最右边的数字
mov ecx, 5 ;数字位数
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 ;消息长度
mov ecx,msg ;消息
mov ebx,1 ;文件描述 (stdout)
mov eax,4 ;系统调用数 (sys_write)
int 0x80 ;调用内核
mov edx,5 ;消息长度
mov ecx,sum ;消息
mov ebx,1 ;文件描述 (stdout)
mov eax,4 ;系统调用数 (sys_write)
int 0x80 ;调用内核
mov eax,1 ;系统调用数 (sys_exit)
int 0x80 ;调用内核
section .data
msg db 'The Sum is:',0xa
len equ $ - msg
num1 db '12345'
num2 db '23456'
sum db ' '
结果如下:
The Sum is:
35801