数值数据通常用二进制表示.算术指令对二进制数据进行操作.当数字显示在屏幕上或从键盘输入时,它们是ASCII格式.
到目前为止,我们已将这种ASCII格式的输入数据转换为二进制数,用于算术计算并将结果转换回来二进制.以下代码显示了此 :
section.text global _start ;must be declared for using gcc_start: ;tell linker entry point moveax,'3' sub eax, '0' mov ebx, '4' sub ebx, '0' add eax, ebx addeax, '0' mov [sum], eax movecx,msg movedx, len movebx,1 ;file descriptor (stdout) moveax,4 ;system call number (sys_write) int0x80 ;call kernel movecx,sum movedx, 1 movebx,1 ;file descriptor (stdout) moveax,4 ;system call number (sys_write) int0x80 ;call kernel moveax,1 ;system call number (sys_exit) int0x80 ;call kernelsection .datamsg db "The sum is:", 0xA,0xD len equ $ - msg segment .bsssum 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 movedx,len ;message length movecx,msg ;message to write movebx,1 ;file descriptor (stdout) moveax,4 ;system call number (sys_write) int0x80 ;call kernel movedx,1 ;message length movecx,res ;message to write movebx,1 ;file descriptor (stdout) moveax,4 ;system call number (sys_write) int0x80 ;call kernel moveax,1 ;system call number (sys_exit) int0x80 ;call kernelsection.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存储为 :
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 clcadd_loop: mov al, [num1 + esi] adc al, [num2 + esi] aaa pushf or al, 30h popf mov[sum + esi], al decesi loopadd_loop movedx,len ;message length movecx,msg ;message to write movebx,1 ;file descriptor (stdout) moveax,4 ;system call number (sys_write) int0x80 ;call kernel movedx,5 ;message length movecx,sum ;message to write movebx,1 ;file descriptor (stdout) moveax,4 ;system call number (sys_write) int0x80 ;call kernel moveax,1 ;system call number (sys_exit) int0x80 ;call kernelsection.datamsg db 'The Sum is:',0xalen equ $ - msgnum1 db '12345'num2 db '23456'sum db ' '
当编译并执行上述代码时,它会产生以下结果 :
The Sum is:35801