汇编语言 数字
数值数据通常用二进制表示。算术指令对二进制数据进行操作。当数字显示在屏幕上或从键盘输入时,它们是 ASCII 形式。到目前为止,我们已经将该输入数据以 ASCII 形式转换为二进制以进行算术计算,并将结果转换回二进制。
下面看一个实例:
section .textglobal _start ;必须声明 gcc_start: ;告诉链接器入口点mov eax,'3'sub eax, '0'mov ebx, '4'sub ebx, '0'add eax, ebxadd eax, '0'mov [sum], eaxmov ecx,msgmov edx, lenmov ebx,1 ;文件描述 (stdout)mov eax,4 ;系统调用号 (sys_write)int 0x80 ;调用内核mov ecx,summov edx, 1mov ebx,1 ;文件描述 (stdout)mov eax,4 ;系统调用号 (sys_write)int 0x80 ;调用内核mov eax,1 ;系统调用号 (sys_exit)int 0x80 ;调用内核section .datamsg db "The sum is:", 0xA,0xDlen equ $ - msgsegment .bsssum 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 .textglobal _start ;必须声明 gcc_start: ;告诉链接器入口点sub ah, ahmov al, '9'sub al, '3'aasor al, 30hmov [res], axmov 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 .datamsg db 'The Result is:',0xalen equ $ - msgsection .bssres 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 .textglobal _start ;必须声明才能使用 gcc_start: ;告诉链接器入口点mov esi, 4 ;指向最右边的数字mov ecx, 5 ;数字位数clcadd_num:mov al, [num1 + esi]adc al, [num2 + esi]aaapushfor al, 30hpopfmov [sum + esi], aldec esinum add_nummov 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 .datamsg db 'The Sum is:',0xalen equ $ - msgnum1 db '12345'num2 db '23456'sum db ' '
结果如下:
The Sum is:35801