조립-번호

수치 데이터는 일반적으로 이진 시스템으로 표현됩니다. 산술 명령어는 이진 데이터에서 작동합니다. 화면에 숫자를 표시하거나 키보드로 입력하면 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 표현에서 10 진수는 ASCII 문자열로 저장됩니다. 예를 들어, 10 진수 값 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 표현에서 각 바이트는 10 진수에 해당하는 이진을 저장합니다. 예를 들어, 숫자 1234는 다음과 같이 저장됩니다.

01	02	03	04H

이 번호를 처리하는 데는 두 가지 지침이 있습니다.

  • AAM − 곱셈 후 ASCII 조정

  • AAD − 분할 전 ASCII 조정

4 개의 ASCII 조정 명령어 인 AAA, AAS, AAM 및 AAD는 압축 해제 된 BCD 표현과 함께 사용할 수도 있습니다. 압축 된 BCD 표현에서 각 숫자는 4 비트를 사용하여 저장됩니다. 두 개의 십진수가 바이트로 압축됩니다. 예를 들어, 숫자 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