PC consists of processor, memory, registers
- Registers are processor components that hold data and addresses
To execute a programme, the system copies data from the external device into the internal memory. The processor executes the programme's instructions
- Byte = One-byte integer -> ends with b
- Word = Two-byte integer -> ends with w
- Doubleword = Four-byte integer -> ends with l
- Quadword = Eight-byte integer -> ends with q
The Assembly Programme is divided into 3 sections
- Data Section = Declaring initialised data or constants
- BSS Section = Declaring variables
- Text Section = Has the actual code. Must start with
global _start
to tell the kernel where the programme's execution is
In Assembly, comments start with ;
Operand Specifiers
- Imm refers to a constant value, e.g. 0x8048d8e or 48
- Ex refers to a register, e.g. %rax
- R[Ex] refers to the value stored in register Ex and
- M[x] refers to the value stored at memory address x.
Type
Immediate
Register
Memory
Memory
Memory
From
$Imm
Ea
Imm
(Ea)
Imm(Eb, Ei. s)
Operand Value
Imm
R[Ea]
M[Imm]
M[R[Ea]]
M[Imm + R[Eb] + (R[Ei ] x s)]
Name
Immediate
Register
Absolute
Absolute
Scaled index
Type
Immediate
Register
Memory
Memory
Memory
From
$Imm
Ea
Imm
(Ea)
Imm(Eb, Ei. s)
Description
Provide the constant value
Specify the memory address
To specify the registers you want to move from
If you don't know the exact address you are moving from, but you know the relative distance*
*E.g
Address Number
0
1
2
Value Stored
a
b
c
Jump Instructions
- Like a "go-to" statement
- To shift execution from the current instruction to some other instruction in the code
Register Usage
%rax, %rcx, %rdx, %rdi, rsi, %rsp, %r8-r11
caller-save registers are not necessarily saved across function calls%rax
is used to store a function's return value, if there is a return value and it is no larger than 64 bits. Otherwise larger return types like structs are returned using the stack%rbx, %rbp, %r12-r15
are callee-saved registers, so they are saved across function calls- So when you are moving from one function to another function the values stored in these functions are retained
%rsp
is used as the stack pointer, a pointer to the topmost element in the stack- It points to the next instrucction that needs to be executed
- This is important because programmes that have code that switch between functions and go inside loops so you need to store the next instruction to be executed
- Flag registers are used to store the data related to the flag for where the stack pointer is pointing to
%rdi, %rsi, %rdx, %rcx, %r8, %r9
are used to pass the first 6 integer or pointer parameters to called functions (used to pass parameters from the caller functions to the callee function)
C code
#include <stdio.h>
int main() {
int x = 3;
int y = 4;
if(x > y) {
x++;
}
else {
y++;
}
return 0;
}
CAssembly Code
.file "sample.c"
.text
.global main
.type main, @function
main:
; initial ebp and esp commands
movl $3, %eax ;moving 3 into %eax registers
movl $4, %ebx ;moving 4 into %ebx registers
cmpl %ebx, %eax ; (3-4 = -1) comparing the contents of the registers & storing it in a flag register
jle .L2 ; jump to L2 if less than or equal to
addl $1, %eax ; else statement part 1
jmp .L3 ; else statement part 2
.L2:
addl $1, %ebx
.L3:
movl $0, %eax ; for return statement
ret
.size main, .-main
.ident "GCC: Ubuntu 7.4.0-1ubuntul~18.04.1) 7.4.0"
.section .note.GNU-stack, "", @progbits
ASM#include <stdio.h>
int main() {
int x = 3;
while(x >= 0) {
printf("%d\n", x);
x--;
}
return 0;
}
C.file "sample2.c"
.text
.section .rodata.str1.1, "aMS", @progbits, 1
.LCO:
.string "%d\n"
main:
movl $3, %ebx
jmp .L2
.L3:
call printf # uses .LCO performs the printf() call
subl $1, %ebx # 3-1 = 2 in %ebx
.L2: # while loop part 1
cmpl $0, %ebx # if the result of the comparison is NOT zero go to l3; while loop part 2
# After jumping to .L3 when we return to -L2 we start again from the top at "cmpl..."
jns .L3 # while loop part 3
movl $0, %eax # For return statement; %eax is return register
ret
.size main, .-main
.ident "GCC: Ubuntu 7.4.0-1ubuntul~18.04.1) 7.4.0"
.section .note.GNU-stack, "", @progbits
ASM- The way jump works is that if you are in instruction 3 and you jump to instruction 5 the next instruction to be executed is instruction 6 not instruction 4
- All the loops can be implemented in terms of labels, jumps and comparisons
- Where you compare something and you keep looping through the labels until the comparison result is not as expected and you continue to the next part