Инструкция INC используется для увеличения операнда на единицу. Он работает с одним операндом, который может находиться либо в регистре, либо в памяти.
Синтаксис
Инструкция INC имеет следующий синтаксис —
INC destination
Назначением операнда может быть 8-битный, 16-битный или 32-битный операнд.
пример
INC EBX ; Increments 32-bit register INC DL ; Increments 8-bit register INC [count] ; Increments the count variable
Инструкция DEC
Инструкция DEC используется для уменьшения операнда на единицу. Он работает с одним операндом, который может находиться либо в регистре, либо в памяти.
Синтаксис
Инструкция 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 инструкции
Команды ADD и SUB используются для выполнения простого сложения / вычитания двоичных данных в байтах, размерах слова и двойного слова, то есть для сложения или вычитания 8-битных, 16-битных или 32-битных операндов соответственно.
Синтаксис
Инструкции 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 / IMUL
Есть две инструкции для умножения двоичных данных. Инструкция MUL (Multiply) обрабатывает неподписанные данные, а IMUL (Integer Multiply) обрабатывает подписанные данные. Обе инструкции влияют на флаг переноса и переполнения.
Синтаксис
Синтаксис для инструкций 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. |
Когда два байта умножены —
Умножитель находится в регистре AL, а множитель — это байт в памяти или в другом регистре. Продукт находится в AX. Старшие 8 битов продукта хранятся в AH, а младшие 8 битов хранятся в AL.
Когда умножаются два значения в одно слово
Умножитель должен быть в регистре AX, а множитель — это слово в памяти или другой регистр. Например, для такой инструкции, как MUL DX, вы должны сохранить множитель в DX и умножить в AX.
В результате получается двойное слово, для которого понадобятся два регистра. Часть высшего порядка (крайняя слева) сохраняется в DX, а часть нижнего порядка (крайняя справа) сохраняется в AX.
Когда два значения двойного слова умножаются —
Когда умножаются два значения двойного слова, множитель должен быть в 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 / IDIV
Операция деления генерирует два элемента — частное и остаток . В случае умножения переполнение не происходит, потому что регистры двойной длины используются для хранения продукта. Однако в случае деления может произойти переполнение. Процессор генерирует прерывание, если происходит переполнение.
Инструкция DIV (Divide) используется для данных без знака, а IDIV (Integer Divide) используется для данных со знаком.
Синтаксис
Формат для инструкции 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. |
Когда делитель равен 1 байту —
Предполагается, что дивиденд находится в регистре AX (16 бит). После деления частное переходит в регистр AL, а остальное — в регистр AH.
Когда делителем является 1 слово —
Предполагается, что дивиденды имеют длину 32 бита и в регистрах DX: AX. Старшие 16 битов находятся в DX, а младшие 16 битов — в AX. После деления 16-битное отношение попадает в регистр AX, а 16-битное значение попадает в регистр DX.
Когда делитель двойное слово —
Предполагается, что размер дивиденда составляет 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
Когда приведенный выше код компилируется и выполняется, он дает следующий результат —