Arithemetic instructions
Perform mathematical computations on data.
With Arithemetic Instructions we can perform mathematical computations on data in registers and memory addresses. These are usually processed by the ALU in the CPU. There are 2 types of instructions:
Unary: Take online 1 operand.
Binary: Takes 2 operands.
Unary instructions
The main Unary instructions when using rax
start as 1.:
inc
Increment by 1
inc rax
-> rax++
or rax += 1
-> rax = 2
dec
Decrement by 1
dec rax
-> rax--
or rax -= 1
-> rax = 0
Lets make a small program that increments by 1
global _start
section .text
_start:
mov al, 0
mov bl, 0
inc bl
gef➤ b _start
gef➤ r
# returns
─────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
→ 0x40100a <_start+10> inc bl
───────────────────────────────────────────────────────────────────────────────────── registers ────
$rbx : 0x1
Binary instructions
We'll assume that both rax
and rbx
start as 1
for each instruction.
add
Add both operands
add rax, rbx
-> rax = 1 + 1
sub
Subtract Source from Destination
sub rax, rbx
-> rax = 1 - 1
imul
Multiply both operands
sub rax, rbx
-> rax = 1 - 1
Lets make a small program with add
.
global _start
section .text
_start:
mov al, 0
mov bl, 0
inc bl
add rax, rbx
We can see after processing the instruction rax is now equal to 0x1. Sub and imul work the same way.
gef➤ b _start
Breakpoint 1 at 0x401000
gef➤ r
─────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x401004 <_start+4> inc bl
→ 0x401006 <_start+6> add rax, rbx
───────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x1
$rbx : 0x1
Bitwise instructions
Bitwise instructions are instructions that work bit level, assuming rax = 1 and rbx = 2 for each instruction.
not
Bitwise NOT (invert all bits, 0->1 and 1->0)
not rax
-> NOT 00000001
-> 11111110
and
Bitwise AND (if both bits are 1 -> 1, if bits are different -> 0)
and rax, rbx
-> 00000001 AND 00000010
-> 00000000
or
Bitwise OR (if either bit is 1 -> 1, if both are 0 -> 0)
or rax, rbx
-> 00000001 OR 00000010
-> 00000011
xor
Bitwise XOR (if bits are the same -> 0, if bits are different -> 1)
xor rax, rbx
-> 00000001 XOR 00000010
-> 00000011
; not instruction
mov rax, 1 ; rax = 1 (0001 in binary)
not rax ; inverts all bits: (1110 in binary)
; and instruction
mov rax, 5 ; 0101
mov rbx, 3 ; 0011
and rax, rbx ; 0001 (1 because only rightmost bit is 1 in both)
; or instruction
mov rax, 5 ; 0101
mov rbx, 3 ; 0011
or rax, rbx ; 0111 (if either bit is 1, result is 1)
XOR Instruction
The XOR (eXclusive OR) instruction is a bitwise operation that compares two bits. It returns 1 if the two bits are different, and 0 if they are the same. Since every bit in rax
is similar and is being compared to itself, the result is a register filled with zeros.
global _start
section .text
_start:
xor rax, rax
xor rbx, rbx
inc rbx
add rax, rbx
$ ./assembler.sh fib.s -g
gef➤ b _start
Breakpoint 1 at 0x401000
gef➤ r
─────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
→ 0x401001 <_start+1> xor eax, eax
0x401003 <_start+3> xor ebx, ebx
───────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x0
$rbx : 0x0
─────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
→ 0x40100c add BYTE PTR [rax], al
───────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x1
$rbx : 0x1
Last updated
Was this helpful?