조립-산술 지침

INC 지침

INC 명령어는 피연산자를 1 씩 증가시키는 데 사용됩니다. 레지스터 또는 메모리에있을 수있는 단일 피연산자에서 작동합니다.

통사론

INC 명령어는 다음과 같은 구문을 가지고 있습니다.

INC destination

피연산자 대상 은 8 비트, 16 비트 또는 32 비트 피연산자 일 수 있습니다.

INC EBX	     ; Increments 32-bit register
INC DL       ; Increments 8-bit register
INC [count]  ; Increments the count variable

DEC 지침

DEC 명령어는 피연산자를 1 씩 감소시키는 데 사용됩니다. 레지스터 또는 메모리에있을 수있는 단일 피연산자에서 작동합니다.

통사론

DEC 명령어는 다음과 같은 구문을 갖습니다.

DEC destination

피연산자 대상 은 8 비트, 16 비트 또는 32 비트 피연산자 일 수 있습니다.

segment .data
   count dw  0
   value db  15
	
segment .text
   inc [count]
   dec [value]
	
   mov ebx, count
   inc word [ebx]
	
   mov esi, value
   dec byte [esi]

ADD 및 SUB 지침

ADD 및 SUB 명령어는 바이트, 워드 및 더블 워드 크기의 이진 데이터의 단순 더하기 / 빼기를 ​​수행하는 데 사용됩니다. 즉, 각각 8 비트, 16 비트 또는 32 비트 피연산자를 더하거나 빼는 데 사용됩니다.

통사론

ADD 및 SUB 명령어에는 다음과 같은 구문이 있습니다.

ADD/SUB	destination, source

ADD / SUB 명령어는-

  • 등록하려면 등록
  • 등록 할 메모리
  • 메모리에 등록
  • 상수 데이터에 등록
  • 일정한 데이터에 대한 메모리

그러나 다른 명령어와 마찬가지로 ADD / SUB 명령어를 사용하여 메모리 대 메모리 작업을 수행 할 수 없습니다. ADD 또는 SUB 작업은 오버플로 및 캐리 플래그를 설정하거나 지 웁니다.

다음 예제는 사용자에게 두 자리 숫자를 요청하고 EAX 및 EBX 레지스터에 각각 숫자를 저장하고 값을 추가하고 결과를 메모리 위치 ' res '에 저장하고 마지막으로 결과를 표시합니다.

SYS_EXIT  equ 1
SYS_READ  equ 3
SYS_WRITE equ 4
STDIN     equ 0
STDOUT    equ 1

segment .data 

   msg1 db "Enter a digit ", 0xA,0xD 
   len1 equ $- msg1 

   msg2 db "Please enter a second digit", 0xA,0xD 
   len2 equ $- msg2 

   msg3 db "The sum is: "
   len3 equ $- msg3

segment .bss

   num1 resb 2 
   num2 resb 2 
   res resb 1    

section	.text
   global _start    ;must be declared for using gcc
	
_start:             ;tell linker entry point
   mov eax, SYS_WRITE         
   mov ebx, STDOUT         
   mov ecx, msg1         
   mov edx, len1 
   int 0x80                

   mov eax, SYS_READ 
   mov ebx, STDIN  
   mov ecx, num1 
   mov edx, 2
   int 0x80            

   mov eax, SYS_WRITE        
   mov ebx, STDOUT         
   mov ecx, msg2          
   mov edx, len2         
   int 0x80

   mov eax, SYS_READ  
   mov ebx, STDIN  
   mov ecx, num2 
   mov edx, 2
   int 0x80        

   mov eax, SYS_WRITE         
   mov ebx, STDOUT         
   mov ecx, msg3          
   mov edx, len3         
   int 0x80

   ; moving the first number to eax register and second number to ebx
   ; and subtracting ascii '0' to convert it into a decimal number
	
   mov eax, [num1]
   sub eax, '0'
	
   mov ebx, [num2]
   sub ebx, '0'

   ; add eax and ebx
   add eax, ebx
   ; add '0' to to convert the sum from decimal to ASCII
   add eax, '0'

   ; storing the sum in memory location res
   mov [res], eax

   ; print the sum 
   mov eax, SYS_WRITE        
   mov ebx, STDOUT
   mov ecx, res         
   mov edx, 1        
   int 0x80

exit:    
   
   mov eax, SYS_EXIT   
   xor ebx, ebx 
   int 0x80

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

Enter a digit:
3
Please enter a second digit:
4
The sum is:
7

The program with hardcoded variables −

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

MUL / IMUL 명령어

이진 데이터를 곱하는 데는 두 가지 지침이 있습니다. MUL (Multiply) 명령어는 부호없는 데이터를 처리하고 IMUL (Integer Multiply)은 부호있는 데이터를 처리합니다. 두 명령어 모두 Carry 및 Overflow 플래그에 영향을줍니다.

통사론

MUL / IMUL 명령어의 구문은 다음과 같습니다.

MUL/IMUL multiplier

두 경우 모두 곱셈기는 곱셈기와 곱셈기의 크기에 따라 누산기에 있으며 생성 된 제품도 피연산자의 크기에 따라 두 개의 레지스터에 저장됩니다. 다음 섹션에서는 세 가지 경우에 대한 MUL 명령어를 설명합니다.

Sr. 아니. 시나리오
1

When two bytes are multiplied −

승수는 AL 레지스터에 있고 승수는 메모리 또는 다른 레지스터의 바이트입니다. 제품은 AX에 있습니다. 제품의 상위 8 비트는 AH에 저장되고 하위 8 비트는 AL에 저장됩니다.

2

When two one-word values are multiplied −

승수는 AX 레지스터에 있어야하며 승수는 메모리 또는 다른 레지스터의 단어입니다. 예를 들어 MUL DX와 같은 명령어의 경우 승수를 DX에 저장하고 승수를 AX에 저장해야합니다.

결과 제품은 두 개의 레지스터가 필요한 더블 워드입니다. 상위 (가장 왼쪽) 부분은 DX에 저장되고 하위 (가장 오른쪽) 부분은 AX에 저장됩니다.

When two doubleword values are multiplied −

두 개의 더블 워드 값을 곱할 때 곱셈은 EAX에 있어야하며 곱셈기는 메모리 또는 다른 레지스터에 저장된 더블 워드 값입니다. 생성 된 제품은 EDX : EAX 레지스터에 저장됩니다. 즉, 상위 32 비트는 EDX 레지스터에 저장되고 하위 32 비트는 EAX 레지스터에 저장됩니다.

MOV AL, 10
MOV DL, 25
MUL DL
...
MOV DL, 0FFH	; DL= -1
MOV AL, 0BEH	; AL = -66
IMUL DL

다음 예제는 3에 2를 곱하고 결과를 표시합니다.

section	.text
   global _start    ;must be declared for using gcc
	
_start:             ;tell linker entry point

   mov	al,'3'
   sub     al, '0'
	
   mov 	bl, '2'
   sub     bl, '0'
   mul 	bl
   add	al, '0'
	
   mov 	[res], al
   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,res
   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 result is:", 0xA,0xD 
len equ $- msg   
segment .bss
res resb 1

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

The result is:
6

DIV / IDIV 지침

나누기 작업은 두 가지 요소를 생성합니다. quotient 그리고 remainder. 곱셈의 경우 제품을 유지하기 위해 2 배 길이 레지스터를 사용하므로 오버플로가 발생하지 않습니다. 단, 분할의 경우 오버 플로우가 발생할 수 있습니다. 오버플로가 발생하면 프로세서가 인터럽트를 생성합니다.

DIV (나누기) 명령어는 부호없는 데이터에 사용되며 IDIV (정수 나누기)는 부호있는 데이터에 사용됩니다.

통사론

DIV / IDIV 명령어의 형식-

DIV/IDIV	divisor

배당금은 누산기에 있습니다. 두 명령어 모두 8 비트, 16 비트 또는 32 비트 피연산자와 함께 작동 할 수 있습니다. 이 작업은 6 개의 상태 플래그 모두에 영향을줍니다. 다음 섹션에서는 피연산자 크기가 다른 세 가지 분할 사례를 설명합니다.

Sr. 아니. 시나리오
1

When the divisor is 1 byte −

피제수는 AX 레지스터 (16 비트)에 있다고 가정합니다. 나눈 후 몫은 AL 레지스터로 이동하고 나머지는 AH 레지스터로 이동합니다.

2

When the divisor is 1 word −

피제수는 길이가 32 비트이고 DX : AX 레지스터에 있다고 가정합니다. 상위 16 비트는 DX에 있고 하위 16 비트는 AX에 있습니다. 나눗셈 후 16 비트 몫은 AX 레지스터로 이동하고 16 비트 나머지는 DX 레지스터로 이동합니다.

When the divisor is doubleword −

피제수는 64 비트 길이이며 EDX : EAX 레지스터에 있다고 가정합니다. 상위 32 비트는 EDX에 있고 하위 32 비트는 EAX에 있습니다. 나눗셈 후 32 비트 몫은 EAX 레지스터로 이동하고 32 비트 나머지는 EDX 레지스터로 이동합니다.

다음 예에서는 8을 2로 나눕니다. dividend 8 에 저장됩니다 16-bit AX register 그리고 divisor 2 에 저장됩니다 8-bit BL register.

section	.text
   global _start    ;must be declared for using gcc
	
_start:             ;tell linker entry point
   mov	ax,'8'
   sub     ax, '0'
	
   mov 	bl, '2'
   sub     bl, '0'
   div 	bl
   add	ax, '0'
	
   mov 	[res], ax
   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,res
   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 result is:", 0xA,0xD 
len equ $- msg   
segment .bss
res resb 1

위의 코드가 컴파일되고 실행되면 다음과 같은 결과가 생성됩니다.

The result is:
4