
彙編 - 數字
數值資料通常以二進位制形式表示。算術指令對二進位制資料進行操作。當數字在螢幕上顯示或從鍵盤輸入時,它們以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_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 ' '
編譯並執行上述程式碼後,將產生以下結果:
The Sum is: 35801
廣告