INC指令用于将操作数递增1.它适用于可以在寄存器或内存中的单个操作数.
INC指令具有以下语法 :
INC destination
操作数目的地可以是8位,16位或32位操作数.
INC EBX;增量32位寄存器 INC DL;增量8位寄存器 INC [count];递增计数变量
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指令用于以字节,字和双字大小执行二进制数据的简单加法/减法,即用于加或减8分别为-bit,16-bit或32-bit操作数.
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
带有硬编码变量的程序 :
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(Multiply)指令处理无符号数据,IMUL(整数乘)处理带符号数据.这两条指令都会影响进位和溢出标志.
MUL/IMUL指令的语法如下 :
MUL/IMUL multiplier
两种情况下的乘数都将在累加器中,具体取决于被乘数的大小以及乘数和生成的乘积也存储在两个寄存器中,具体取决于操作数的大小.以下部分解释了具有三种不同情况的MUL指令 :
Sr.No. | 情景 |
---|---|
1 | 当两个字节相乘 : 去; 被乘数位于AL寄存器中,乘数是存储器或另一个寄存器中的一个字节.该产品在AX中.产品的高阶8位存储在AH中,低阶8位存储在AL中.
|
2 | 当两个单字值乘以 : 去; 被乘数应该在AX寄存器中,乘数是存储器中的一个字或另一个寄存器.例如,对于像MUL DX这样的指令,必须将乘数存储在DX中,并将被乘数存储在AX中. 结果产品是双字,需要两个寄存器.高阶(最左边)部分存储在DX中,低阶(最右边)部分存储在AX中.
|
3 | 当两个双字值乘以 : 去; 当两个双字值相乘时,被乘数应该在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(Divide)指令用于无符号数据,IDIV(整数除法)用于签名数据.
DIV/IDIV指令的格式 :
DIV/IDIV divisor
红利在累加器中.这两条指令都可以用于8位,16位或32位操作数.该操作会影响所有六个状态标志.以下部分介绍了具有不同操作数大小和减号的三种除法案例;
Sr.No. | 情景 |
---|---|
1 | 当除数为1字节 : 假设被除数在AX寄存器中(16位).除法后,商进入AL寄存器,余数进入AH寄存器.
|
2 | 当除数为1字 : 假设被除数为32位且在DX:AX寄存器中.高阶16位在DX中,低阶16位在AX中.除法后,16位商进入AX寄存器,16位余数进入DX寄存器.
|
3 | 当除数为双字 : 假设被除数为64位且在EDX:EAX寄存器.高阶32位在EDX中,低阶32位在EAX中.除法后,32位商进入EAX寄存器,32位余数进入EDX寄存器.
|
以下示例将8除以2. 被除数8 存储在 16位AX寄存器和除数2 存储在 8位BL寄存器中.
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