Assembly-programming-assembly-numbers

提供:Dev Guides
移動先:案内検索

アセンブリ-番号

数値データは通常、バイナリシステムで表されます。 算術命令はバイナリデータを操作します。 数字が画面に表示されるか、キーボードから入力されると、それらは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またはバイナリコード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進数に相当するバイナリが格納されます。 たとえば、番号1234は次のように保存されます-

01  02  03  04H

これらの番号を処理するための2つの指示があります-

  • AAM -乗算後のASCII調整
  • AAD -除算前のASCII調整

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

12  34H

これらの番号を処理するための2つの指示があります-

  • DAA -追加後の10進数調整
  • DAS -減算後の小数調整

パック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