조립-산술 지침
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