汇编语言 数字
-
数字
数值数据通常用二进制表示。算术指令对二进制数据进行操作。当数字显示在屏幕上或从键盘输入时,它们是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表示形式不支持乘法和除法。以下程序将两个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_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 ;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