Assembly - Hướng dẫn số học

Hướng dẫn INC

Lệnh INC được sử dụng để tăng một toán hạng lên một. Nó hoạt động trên một toán hạng duy nhất có thể nằm trong thanh ghi hoặc trong bộ nhớ.

Cú pháp

Lệnh INC có cú pháp sau:

INC destination

Điểm đến của toán hạng có thể là một toán hạng 8 bit, 16 bit hoặc 32 bit.

Thí dụ

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

Hướng dẫn DEC

Lệnh DEC được sử dụng để giảm một toán hạng. Nó hoạt động trên một toán hạng duy nhất có thể nằm trong thanh ghi hoặc trong bộ nhớ.

Cú pháp

Lệnh DEC có cú pháp sau:

DEC destination

Điểm đến của toán hạng có thể là một toán hạng 8 bit, 16 bit hoặc 32 bit.

Thí dụ

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]

Hướng dẫn ADD và SUB

Các lệnh ADD và SUB được sử dụng để thực hiện cộng / trừ dữ liệu nhị phân đơn giản theo kích thước byte, từ và từ đôi, tức là để cộng hoặc trừ các toán hạng 8 bit, 16 bit hoặc 32 bit, tương ứng.

Cú pháp

Các lệnh ADD và SUB có cú pháp sau:

ADD/SUB	destination, source

Lệnh ADD / SUB có thể diễn ra giữa -

  • Đăng ký để đăng ký
  • Bộ nhớ để đăng ký
  • Đăng ký vào bộ nhớ
  • Đăng ký dữ liệu không đổi
  • Bộ nhớ đến dữ liệu không đổi

Tuy nhiên, giống như các lệnh khác, không thể thực hiện các thao tác chuyển bộ nhớ vào bộ nhớ bằng lệnh ADD / SUB. Thao tác ADD hoặc SUB đặt hoặc xóa các cờ tràn và cờ mang.

Thí dụ

Ví dụ sau sẽ yêu cầu hai chữ số từ người dùng, lưu trữ các chữ số trong thanh ghi EAX và EBX, tương ứng, thêm các giá trị, lưu kết quả vào vị trí bộ nhớ ' res ' và cuối cùng hiển thị kết quả.

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

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

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

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

The sum is:
7

Hướng dẫn MUL / IMUL

Có hai hướng dẫn để nhân dữ liệu nhị phân. Lệnh MUL (Multiply) xử lý dữ liệu chưa được ký và IMUL (Integer Multiply) xử lý dữ liệu đã ký. Cả hai hướng dẫn đều ảnh hưởng đến cờ Chở và Tràn.

Cú pháp

Cú pháp cho hướng dẫn MUL / IMUL như sau:

MUL/IMUL multiplier

Phép nhân và trong cả hai trường hợp sẽ nằm trong một bộ tích lũy, tùy thuộc vào kích thước của phép nhân và hệ số nhân và tích được tạo ra cũng được lưu trữ trong hai thanh ghi tùy thuộc vào kích thước của toán hạng. Phần sau giải thích các hướng dẫn MUL với ba trường hợp khác nhau:

Sr.No. Các tình huống
1

When two bytes are multiplied −

Số nhân và nằm trong thanh ghi AL, và số nhân là một byte trong bộ nhớ hoặc trong một thanh ghi khác. Sản phẩm có trong AXE. 8 bit bậc cao của sản phẩm được lưu trong AH và 8 bit bậc thấp được lưu trong AL.

2

When two one-word values are multiplied −

Số nhân và phải nằm trong thanh ghi AX, và số nhân là một từ trong bộ nhớ hoặc một thanh ghi khác. Ví dụ: đối với một lệnh như MUL DX, bạn phải lưu trữ hệ số nhân trong DX và cấp số nhân trong AX.

Sản phẩm kết quả là một từ kép, sẽ cần hai thanh ghi. Phần bậc cao (ngoài cùng bên trái) được lưu trữ trong DX và phần bậc thấp hơn (ngoài cùng bên phải) được lưu trữ trong AX.

3

When two doubleword values are multiplied −

Khi hai giá trị từ kép được nhân lên, thì số nhân và phải nằm trong EAX và hệ số nhân là giá trị từ kép được lưu trữ trong bộ nhớ hoặc trong một thanh ghi khác. Sản phẩm được tạo ra được lưu trữ trong thanh ghi EDX: EAX, tức là 32 bit bậc cao được lưu trong thanh ghi EDX và 32 bit bậc thấp được lưu trong thanh ghi EAX.

Thí dụ

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

Thí dụ

Ví dụ sau nhân 3 với 2 và hiển thị kết quả:

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

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

The result is:
6

Hướng dẫn DIV / IDIV

Phép toán phân chia tạo ra hai phần tử - a quotient và một remainder. Trong trường hợp nhân, tràn không xảy ra vì các thanh ghi độ dài kép được sử dụng để giữ tích. Tuy nhiên, trong trường hợp phân chia, tràn có thể xảy ra. Bộ xử lý tạo ra một ngắt nếu xảy ra tràn.

Lệnh DIV (Chia) được sử dụng cho dữ liệu chưa có dấu và IDIV (Chia số nguyên) được sử dụng cho dữ liệu có dấu.

Cú pháp

Định dạng cho lệnh DIV / IDIV -

DIV/IDIV	divisor

Cổ tức nằm trong một bộ tích lũy. Cả hai lệnh đều có thể hoạt động với các toán hạng 8 bit, 16 bit hoặc 32 bit. Thao tác này ảnh hưởng đến tất cả sáu cờ trạng thái. Phần sau giải thích ba trường hợp chia với kích thước toán hạng khác nhau:

Sr.No. Các tình huống
1

When the divisor is 1 byte −

Cổ tức được giả định là trong thanh ghi AX (16 bit). Sau khi chia, thương sẽ đi vào thanh ghi AL và phần còn lại đi vào thanh ghi AH.

2

When the divisor is 1 word −

Cổ tức được giả định là dài 32 bit và trong thanh ghi DX: AX. 16 bit bậc cao nằm trong DX và 16 bit bậc thấp nằm trong AX. Sau khi phân chia, thương số 16 bit đi vào thanh ghi AX và phần còn lại 16 bit đi vào thanh ghi DX.

3

When the divisor is doubleword −

Cổ tức được giả định là dài 64 bit và trong thanh ghi EDX: EAX. 32 bit bậc cao nằm trong EDX và 32 bit bậc thấp trong EAX. Sau khi phân chia, thương số 32 bit đi vào thanh ghi EAX và phần còn lại 32 bit sẽ đi đến thanh ghi EDX.

Thí dụ

Ví dụ sau chia 8 với 2. dividend 8 được lưu trữ trong 16-bit AX registerdivisor 2 được lưu trữ trong 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

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

The result is:
4