Montaj - Aritmetik Talimatlar

INC Talimatı

INC komutu, bir işleneni birer birer artırmak için kullanılır. Bir yazmaçta veya bellekte olabilen tek bir işlenen üzerinde çalışır.

Sözdizimi

INC komutu aşağıdaki sözdizimine sahiptir -

INC destination

İşlenen hedefi 8 bitlik, 16 bitlik veya 32 bitlik bir işlenen olabilir.

Misal

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

DEC Talimatı

DEC komutu, bir işleneni birer birer azaltmak için kullanılır. Bir yazmaçta veya bellekte olabilen tek bir işlenen üzerinde çalışır.

Sözdizimi

DEC talimatı aşağıdaki sözdizimine sahiptir -

DEC destination

İşlenen hedefi 8 bitlik, 16 bitlik veya 32 bitlik bir işlenen olabilir.

Misal

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 ve SUB Talimatları

ADD ve SUB komutları, ikili verilerin bayt, kelime ve çift kelime boyutunda basit toplama / çıkarma işlemlerini gerçekleştirmek için, yani sırasıyla 8 bit, 16 bit veya 32 bit işlenenleri eklemek veya çıkarmak için kullanılır.

Sözdizimi

ADD ve SUB komutları aşağıdaki sözdizimine sahiptir -

ADD/SUB	destination, source

ADD / SUB komutu aşağıdakiler arasında gerçekleşebilir -

  • Kaydolmak için kaydolun
  • Kaydedilecek hafıza
  • Hafızaya kaydol
  • Sabit verilere kaydolun
  • Sabit verilere bellek

Ancak, diğer talimatlar gibi, ADD / SUB komutları kullanılarak bellekten belleğe işlemler mümkün değildir. Bir ADD veya SUB işlemi taşma ve taşıma bayraklarını ayarlar veya siler.

Misal

Aşağıdaki örnek, kullanıcıdan iki basamak isteyecek, basamakları sırasıyla EAX ve EBX kaydında depolayacak, değerleri ekleyecek, sonucu bir bellek konumuna ' res ' depolayacak ve son olarak sonucu görüntüleyecektir.

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

Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki sonucu verir -

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

Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki sonucu verir -

The sum is:
7

MUL / IMUL Talimatı

İkili verileri çarpmak için iki talimat vardır. MUL (Çarpma) talimatı işaretsiz verileri işler ve IMUL (Tamsayı Çarpma) işaretli verileri işler. Her iki talimat da Taşıma ve Taşma bayrağını etkiler.

Sözdizimi

MUL / IMUL komutlarının sözdizimi aşağıdaki gibidir -

MUL/IMUL multiplier

Her iki durumda da çarpan, çarpanın boyutuna ve çarpana bağlı olarak bir toplayıcıda olacaktır ve üretilen ürün ayrıca işlenenlerin boyutuna bağlı olarak iki kayıtta saklanır. Aşağıdaki bölüm MUL talimatlarını üç farklı durumla açıklamaktadır -

Sr.No. Senaryolar
1

When two bytes are multiplied −

Çarpan AL yazmacında bulunur ve çarpan bellekte veya başka bir yazmaçta bir bayttır. Ürün AX'te. Ürünün yüksek sıralı 8 biti AH'de depolanır ve düşük sıralı 8 biti AL'de depolanır.

2

When two one-word values are multiplied −

Çarpan, AX kaydında olmalıdır ve çarpan, bellekte veya başka bir kayıtta bir sözcüktür. Örneğin, MUL DX gibi bir talimat için, çarpanı DX'te ve çarpanı AX'te saklamanız gerekir.

Ortaya çıkan ürün, iki kayda ihtiyaç duyan bir çift sözcüktür. Yüksek dereceli (en soldaki) bölüm DX'te saklanır ve alt sıra (en sağdaki) bölüm AX'te depolanır.

3

When two doubleword values are multiplied −

İki doubleword değeri çarpıldığında, çarpan EAX'te olmalıdır ve çarpan, bellekte veya başka bir kayıtta saklanan bir çift kelime değeridir. Üretilen ürün, EDX: EAX kayıtlarında depolanır, yani, yüksek sıralı 32 bit, EDX kaydında depolanır ve düşük sıralı 32 bit, EAX kaydında depolanır.

Misal

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

Misal

Aşağıdaki örnek 3'ü 2 ile çarpıyor ve sonucu gösteriyor -

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

Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki sonucu verir -

The result is:
6

DIV / IDIV Talimatları

Bölme işlemi iki öğe oluşturur - a quotient ve bir remainder. Çarpma durumunda, ürünü tutmak için çift uzunluklu yazmaçlar kullanıldığından taşma meydana gelmez. Ancak bölünme durumunda taşma meydana gelebilir. İşlemci, taşma meydana gelirse bir kesinti oluşturur.

DIV (Böl) komutu, işaretsiz veriler için kullanılır ve IDIV (Integer Divide) imzalı veriler için kullanılır.

Sözdizimi

DIV / IDIV talimatı için format -

DIV/IDIV	divisor

Temettü bir akümülatörde. Her iki komut da 8 bit, 16 bit veya 32 bit işlenenlerle çalışabilir. İşlem altı durum bayrağının tümünü etkiler. Aşağıdaki bölüm, farklı işlenen boyutuna sahip üç bölme durumunu açıklamaktadır -

Sr.No. Senaryolar
1

When the divisor is 1 byte −

Temettü, AX kaydında (16 bit) olduğu varsayılır. Bölünmeden sonra, bölüm AL yazmacına gider ve geri kalanı AH yazmacına gider.

2

When the divisor is 1 word −

Temettü tutarının 32 bit uzunluğunda olduğu ve DX: AX kayıtlarında olduğu varsayılır. Yüksek sıralı 16 bit DX'te ve düşük sıralı 16 bit AX'te. Bölünmeden sonra, 16 bitlik bölüm AX yazmacına gider ve 16 bitlik kalan DX yazmacına gider.

3

When the divisor is doubleword −

Temettü tutarının 64 bit uzunluğunda olduğu ve EDX: EAX kayıtlarında olduğu varsayılır. Yüksek sıralı 32 bitler EDX'te ve düşük sıralı 32 bitler EAX'te. Bölünmeden sonra, 32 bitlik bölüm EAX kaydına gider ve 32 bitlik kalan EDX kaydına gider.

Misal

Aşağıdaki örnek 8'i 2'ye böler. dividend 8 içinde saklanır 16-bit AX register ve divisor 2 içinde saklanır 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

Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki sonucu verir -

The result is:
4