开发手册 欢迎您!
软件开发者资料库

汇编 - 算术指令

汇编算术指令 - 从简单和简单的步骤学习汇编编程,从基本概念到高级概念,包括简介,环境设置,基本语法,存储段,状态寄存器,系统调用,寻址模式,变量,常量,算术,条件执行,循环,逻辑,字符串处理,递归,数组,中断,过程,常量,宏,文件,内存管理。

INC指令

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

语法

INC指令具有以下语法 :

  INC destination

操作数目的地可以是8位,16位或32位操作数.

示例

  INC EBX;增量32位寄存器 INC DL;增量8位寄存器 INC [count];递增计数变量

DEC指令

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

语法

DEC指令具有以下语法 :

DEC destination

操作数目的地可以是8位,16位或32位操作数.

示例

segment .data   count dw  0   value db  15segment .text   inc [count]   dec [value]   mov ebx, count   inc word [ebx]   mov esi, value   dec byte [esi]

ADD和SUB指令

ADD和SUB指令用于以字节,字和双字大小执行二进制数据的简单加法/减法,即用于加或减8分别为-bit,16-bit或32-bit操作数.

语法

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

ADD/SUBdestination, source

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

  • 注册注册

  • 要注册的内存

  • 注册到内存

  • 注册到常量数据

  • 内存到常量数据

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

示例

以下示例将询问用户的两位数,存储EAX和EBX寄存器中的数字分别添加值,将结果存储在存储单元" res "中,最后显示结果.

SYS_EXIT  equ 1SYS_READ  equ 3SYS_WRITE equ 4STDIN     equ 0STDOUT    equ 1segment .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 $- msg3segment .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 0x80exit:          mov eax, SYS_EXIT      xor ebx, ebx    int 0x80

当上面的代码是编译并执行,它产生以下结果 :

Enter a digit:3Please enter a second digit:4The sum is:7

带有硬编码变量的程序 :  

section.text   global _start    ;must be declared for using gcc_start:             ;tell linker entry point   moveax,'3'   sub     eax, '0'   mov ebx, '4'   sub     ebx, '0'   add eax, ebx   addeax, '0'   mov [sum], eax   movecx,msg   movedx, len   movebx,1;file descriptor (stdout)   moveax,4;system call number (sys_write)   int0x80;call kernel   movecx,sum   movedx, 1   movebx,1;file descriptor (stdout)   moveax,4;system call number (sys_write)   int0x80;call kernel   moveax,1;system call number (sys_exit)   int0x80;call kernelsection .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(整数乘)处理带符号数据.这两条指令都会影响进位和溢出标志.

语法

MUL/IMUL指令的语法如下 :

MUL/IMUL multiplier

两种情况下的乘数都将在累加器中,具体取决于被乘数的大小以及乘数和生成的乘积也存储在两个寄存器中,具体取决于操作数的大小.以下部分解释了具有三种不同情况的MUL指令 :

Sr.No.情景
1

当两个字节相乘 : 去;

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

Arithmetic1

2

当两个单字值乘以 : 去;

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

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

Arithmetic2

3

当两个双字值乘以 : 去;

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

Arithmetic3

示例

  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   moval,'3'   sub     al, '0'   mov bl, '2'   sub     bl, '0'   mul bl   addal, '0'   mov [res], al   movecx,msg   movedx, len   movebx,1;file descriptor (stdout)   moveax,4;system call number (sys_write)   int0x80;call kernel   movecx,res   movedx, 1   movebx,1;file descriptor (stdout)   moveax,4;system call number (sys_write)   int0x80;call kernel   moveax,1;system call number (sys_exit)   int0x80;call kernelsection .datamsg db "The result is:", 0xA,0xD len equ $- msg   segment .bssres resb 1

当上面的代码编译并执行,它产生以下结果 :

The result is:6

DIV/IDIV指令

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

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

语法

DIV/IDIV指令的格式 :

DIV/IDIVdivisor

红利在累加器中.这两条指令都可以用于8位,16位或32位操作数.该操作会影响所有六个状态标志.以下部分介绍了具有不同操作数大小和减号的三种除法案例;

Sr.No.情景
1

当除数为1字节 :  

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

 Arithmetic4

2

当除数为1字 :  

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

Arithmetic5

3

当除数为双字 :  

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

Arithmetic6

示例

以下示例将8除以2. 被除数8 存储在 16位AX寄存器除数2 存储在 8位BL寄存器中.

section.text   global _start    ;must be declared for using gcc_start:             ;tell linker entry point   movax,'8'   sub     ax, '0'   mov bl, '2'   sub     bl, '0'   div bl   addax, '0'   mov [res], ax   movecx,msg   movedx, len   movebx,1;file descriptor (stdout)   moveax,4;system call number (sys_write)   int0x80;call kernel   movecx,res   movedx, 1   movebx,1;file descriptor (stdout)   moveax,4;system call number (sys_write)   int0x80;call kernel   moveax,1;system call number (sys_exit)   int0x80;call kernelsection .datamsg db "The result is:", 0xA,0xD len equ $- msg   segment .bssres resb 1

当上面的代码被编译并执行,它产生以下结果 :

The result is:4