当前位置: 首页 > 文档资料 > 汇编中文教程 >

算术指令(Arithmetic Instructions)

优质
小牛编辑
141浏览
2023-12-01

INC指令

INC指令用于将操作数递增1。 它适用于单个操作数,可以在寄存器或内存中。

语法 (Syntax)

INC指令具有以下语法 -

INC destination

操作数destination可以是8位,16位或32位操作数。

例子 (Example)

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

DEC指令

DEC指令用于将操作数递减1。 它适用于单个操作数,可以在寄存器或内存中。

语法 (Syntax)

DEC指令具有以下语法 -

DEC destination

操作数destination可以是8位,16位或32位操作数。

例子 (Example)

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位操作数。

语法 (Syntax)

ADD和SUB指令具有以下语法 -

ADD/SUB	destination, source

ADD/SUB指令可以在 - 之间发生 -

  • 注册注册
  • 记忆要注册
  • 注册到内存
  • 注册恒定数据
  • 内存到恒定数据

但是,与其他指令一样,使用ADD/SUB指令无法进行内存到内存操作。 ADD或SUB操作设置或清除溢出和进位标志。

例子 (Example)

以下示例将询问用户的两位数字,分别将数字存储在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(整数乘)处理带符号数据。 这两条指令都会影响进位和溢出标志。

语法 (Syntax)

MUL/IMUL指令的语法如下 -

MUL/IMUL multiplier

两种情况下的复数将位于累加器中,具体取决于被乘数和乘数的大小,并且生成的乘积也根据操作数的大小存储在两个寄存器中。 以下部分介绍了具有三种不同情况的MUL指令 -

Sr.No.方案
1

When two bytes are multiplied −

被乘数位于AL寄存器中,乘数是存储器或另一个寄存器中的一个字节。 该产品在AX。 产品的高阶8位存储在AH中,低阶8位存储在AL中。

Arithmetic1

2

When two one-word values are multiplied −

被乘数应位于AX寄存器中,乘数是存储器中的字或另一个寄存器。 例如,对于像MUL DX这样的指令,必须将乘数存储在DX中,将被乘数存储在AX中。

最终产品是双字,需要两个寄存器。 高阶(最左边)部分存储在DX中,低阶(最右边)部分存储在AX中。

Arithmetic2

3

When two doubleword values are multiplied −

当两个双字值相乘时,被乘数应为EAX,乘数为存储在存储器或另一个寄存器中的双字值。 生成的产品存储在EDX:EAX寄存器中,即高位32位存储在EDX寄存器中,低位32位存储在EAX寄存器中。

Arithmetic3

例子 (Example)

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

例子 (Example)

以下示例将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指令

除法运算生成两个元素 - quotientremainder 。 在乘法的情况下,不会发生溢出,因为使用双倍长度寄存器来保留产品。 但是,在分割的情况下,可能会发生溢出。 如果发生溢出,处理器会产生中断。

DIV(Divide)指令用于无符号数据,IDIV(整数除)用于签名数据。

语法 (Syntax)

DIV/IDIV指令的格式 -

DIV/IDIV	divisor

股息在累加器中。 这两条指令都可以用于8位,16位或32位操作数。 该操作会影响所有六个状态标志。 以下部分介绍了具有不同操作数大小的三种划分案例 -

Sr.No.方案
1

When the divisor is 1 byte −

假设被除数在AX寄存器中(16位)。 除法后,商进入AL寄存器,余数进入AH寄存器。

Arithmetic4

2

When the divisor is 1 word −

假设被除数为32位,在DX:AX寄存器中。 高阶16位在DX中,低阶16位在AX中。 除法后,16位商进入AX寄存器,16位余数进入DX寄存器。

Arithmetic5

3

When the divisor is doubleword −

假设被除数为64位,并且在EDX:EAX寄存器中。 高阶32位在EDX中,低阶32位在EAX中。 除法后,32位商进入EAX寄存器,32位余数进入EDX寄存器。

Arithmetic6

例子 (Example)

以下示例将8除以2. dividend 8存储在16-bit AX registerdivisor 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