アセンブリ-番号

数値データは通常、バイナリシステムで表されます。算術命令はバイナリデータを操作します。数字が画面に表示されたり、キーボードから入力されたりすると、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

ただし、このような変換にはオーバーヘッドがあり、アセンブリ言語プログラミングでは、数値をより効率的な方法でバイナリ形式で処理できます。10進数は2つの形式で表すことができます-

  • ASCII形式
  • BCDまたは2進化10進形式

ASCII表現

ASCII表現では、10進数はASCII文字の文字列として格納されます。たとえば、10進値1234は-として格納されます。

31	32	33	34H

ここで、31Hは1のASCII値、32Hは2のASCII値などです。ASCII表現で数値を処理するための4つの命令があります-

  • 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表現には2つのタイプがあります-

  • 解凍されたBCD表現
  • パックされたBCD表現

アンパックBCD表現では、各バイトに10進数に相当する2進数が格納されます。たとえば、番号1234は-として格納されます

01	02	03	04H

これらの数値を処理するための2つの命令があります-

  • AAM −乗算後のASCII調整

  • AAD −除算前のASCII調整

4つのASCII調整命令、AAA、AAS、AAM、およびAADは、アンパックされたBCD表現でも使用できます。パックBCD表現では、各桁は4ビットを使用して格納されます。10進数の2桁が1バイトにパックされます。たとえば、番号1234は-として格納されます

12	34H

これらの数値を処理するための2つの命令があります-

  • DAA −追加後の10進調整

  • DAS −減算後の10進数調整

パックされたBCD表現では乗算と除算はサポートされていません。

次のプログラムは、2つの5桁の10進数を合計し、その合計を表示します。上記の概念を使用します-

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