數(shù)值數(shù)據(jù)普遍表示二進(jìn)制系統(tǒng)。算術(shù)指令的操作上的二進(jìn)制數(shù)據(jù)。當(dāng)數(shù)字顯示在屏幕上,或從鍵盤輸入,它們是ASCII形式。
到目前為止,我們已經(jīng)轉(zhuǎn)換成ASCII形式輸入數(shù)據(jù)進(jìn)行算術(shù)運(yùn)算的二進(jìn)制結(jié)果轉(zhuǎn)換回二進(jìn)制。下面的代碼顯示:
section .text global _start ;must be declared for using gcc _start: ;tell linker entry yiibai 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
上面的代碼編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生以下結(jié)果:
The sum is: 7
然而,這樣的轉(zhuǎn)換是有一個(gè)系統(tǒng)開銷和匯編語言的程序設(shè)計(jì)允許更有效的方式,處理數(shù)字的二進(jìn)制形式。十進(jìn)制數(shù)可以表示為兩種形式:
ASCII形式
BCD或二進(jìn)制編碼的十進(jìn)制形式
在ASCII碼表示,十進(jìn)制數(shù)字存儲ASCII字符串。例如,十進(jìn)制值1234被存儲為:
31 32 33 34H
其中,31H,32H是ASCII值1 ASCII值2,依此類推。有以下四個(gè)指令處理數(shù)字的ASCII表示:
AAA - ASCII Adjust After Addition
AAS - ASCII Adjust After Subtraction
AAM - ASCII Adjust After Multiplication
AAD - ASCII Adjust Before Division
這些指令不采取任何操作數(shù),并承擔(dān)所需的操作數(shù)是在AL寄存器中。
下面的示例使用AAS指令來說明這個(gè)概念:
section .text global _start ;must be declared for using gcc _start: ;tell linker entry yiibai 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
上面的代碼編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生以下結(jié)果:
The Result is: 6
BCD表示有兩種類型:
未打包BCD表示BCD表示
壓縮BCD表示
在壓縮BCD表示,每個(gè)字節(jié)的存儲的二進(jìn)制相當(dāng)于十進(jìn)制數(shù)字。例如,被存儲為數(shù)字1234:
01 02 03 04H
有兩種處理這些數(shù)字指令:
AAM - 乘法后ASCII調(diào)整
AAD - ASCII除法前調(diào)整
四個(gè)ASCII調(diào)整指令,AAA,AAS,AAM和AAD也可以用壓縮BCD表示。壓縮BCD碼表示,每個(gè)使用四位數(shù)字存儲。兩位十進(jìn)制數(shù)被打包成一個(gè)字節(jié)。例如,被存儲為數(shù)字1234:
12 34H
有兩種處理這些數(shù)字指令:
DAA - Decimal Adjust After Addition
DAS - decimal Adjust After Subtraction
乘法和除法包裝BCD表示不支持。
下面的程序增加了兩個(gè)5位數(shù)的十進(jìn)制數(shù)和顯示的總和。它使用上述的概念:
section .text global _start ;must be declared for using gcc _start: ;tell linker entry yiibai mov esi, 4 ;yiibaiing 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 ' '
上面的代碼編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生以下結(jié)果:
The Sum is: 35801