# Cours ASM
**Important:** Ces notes sont les notes que j'utilise pour préparer les séances de RMD afin d'être à la page sur ce que vous êtes supposés savoir si vous avez vu le cours, **il ne s'agit donc pas d'un résumé du cours** et il peut manquer des infos importantes.
## Cours 1 - Processor Architecture
Opti avant = taille du code
Opti mtn = efficacité du code
Assembleur: contrôle total des instructions
Endianness: ordre des bytes
- control unit = pour gérer les différents acteurs
- ALU (arithmetic and logical unit) = pour compute l'info
- register bank = pour stocker l'info
We need more to execute complex tasks:
- program memory access
- data memory access
Il faut le moins d'accès mémoire possible pour un truc un minimum performant
- caches, mmu (memory management unit = translation between pmem and vmem, cache control, ...)
- different units depending on the data type (integer, floating-point, control, ...)
Today, tout est le même chip -> avant, chaque unit était indépendante (plus lent, moins compact)
Unit:
- fetches and decode instruction
- registers give data
- ALU implements operation
- logical ops = AND, OR, XOR, NOT, NOR
- arithmetic ops = add, sub, mul (not div, requires registers)
- shifts
- compares
- (some instruction may need external data)
Registers: may be seen as variables inside the proc, size depends on the proc
General-purpose registers: (vol. 1, p. 68)
- int (rax, ebx, ...)
- floating-point (ymm0, xmm1, ...)
Specialized registers:
- flags: zero, neg, carry...
- system: mode
Microprogrammed proc = different steps of processing an instruction, but only one at a time, for instance:
- `sub`: fetch, decod, exec, write
- `jmp`: fetch, decod, exec
- `ld` (= load): fetch, decod, exec, mem (= memory access), write

Cons:
- slow because you need to wait for previous step to complete
- more complex = longer
- most of hardware only used once for each instruction (you don't `fetch` twice...)
- most of hardware unused (for instance, when ALU works, nothing else does)
Pros: easy, small, and adding instructions is ez af too (only add it in `decode` + add sequence in `exec`)
=> opti = **pipelined** proc: le proco fonctionne à flux tendu
- split exec in several steps
- each step is a basic op
- each step is associated with a specific hardware part
- all those parts works in parallel

=> speed up the pipeline by splitting the slowest operation
CISC (complex instruction set computer) = instructions complexes qui permettent de faire beaucoup de choses
- pros: 1 instruction peut faire beaucoup de choses, beaucoup d'operations, easier to write and to compress
- cons: variable-len instructions, requires complex hardware
RISC (reduced instruction set computer) = une instruction = 1 opération, on fait qu'une chose à la fois
- pros: simple, fixed-len instructions, decoding requires simple hardware
- cons: longer programs, harder to optimize
-> modern procs often translate CISC to RISC
## Cours 2 - Memory
Used to:
- fetch instructions
- access data
Von Neuman architecture: data et instructions au même espace d'adressage
Harvard architecture: data et instructions dans 2 espaces mémoires physiques séparés
**Immediate addressing**
- *value* of data is directly stored in the *instruction*
- no memory access needed
```x86asm
add $2, %rdi
```
**Absolute addressing**
- *address* of data is stored directly in the *instruction* (ultra rare, on sait rarement où se situe la data qui nous intéresse)
- memory access needed to get value inside the address
```x86asm
mov [0x830], %rdi
```
**Register indirect addressing**
- *address* of data is stored in a *register*
- memory access needed to get value inside the address stored in the register
```x86asm
mov [%rsi], %rdi
```
**Complex addressing**
- Register indirect with base register
- Register indirect with offset
- ...
```x86asm
mov [%rsi + 0x123], %rdi
mov [%rsi + %rax], %rdi
```
Alignement est une histoire de data type width, les accès non-alignés sont beaucoup plus lents, parfois même interdits selon les procs
In a structure, fields are stored in declaration order and they must all be aligned

Si on a pas un cas idéal comme au dessus, le compilo add du padding pour garder l'alignement

= gain de vitesse mais perte de place (padding bytes are unused)
Avec `__attribute__((packed))` on peut forcer le fait de ne pas aligner les fields = pas de padding donc moins rapide mais pas de perte de place (en vrai c'est rarement utile à notre niveau)
**Endianness** = le sens dans lequel on lit la donnée i.e. si le "poids fort" est à droite ou à gauche
**Cache memory**:
- local copy of central memory
- transparent (invisible pour nous)
- volatile = peut être flushed à tout moment
- faster, closer to CPU
- mais cher
Plusieurs caches de différentes taille, vitesses, latences... Chaque cache est à une distance différente du CPU
Memory address space in contiguous (physically) and be mapped to another address space (virtually)
La mémoire est découpée en segments qu'on définit par:
- segment base address in target address space (début du segment)
- segment size
- segment type and access rights (read, write, execute)
Pour gérer les segments: segment descriptor table
Limitations:
- address-space must be mapped at contiguous blocks donc compliqué d'extend un segment
- on ne peut pas avoir de "bouts de segments"
Modern OS use **pages** to split address space. On les définit par
- address in target address space
- type + access rights
- size
- other: cachability, ...
Pour gérer les pages: page descriptor table
Better than segments:
- addresses spaces may be mapped to uncontiguous target page (remember malloc)
- sharing, swapping...
**Memory protection** to protect:
- system from hosted processes
- hosted processes from each other
`cr3` est registre qui hold le PDBR (Page Directory Base Register) qui permet d'accéder aux pages d'un process
Branch principle: modify execution flow
- `call` = save return address (pushed onto the stack)
- `jmp` = nothing is saved, flow execution just go to destination
- `jge`, `jne`, ... = conditional jump
(WIP - à terminer)
## Cours 3 - Handling events and OS generalities
*interrupt*: caused by external event
*exception*: caused by instruction execution
*synchronous*: vient d'un effet du code, on peut plus ou moins le prévoir (syscall, page fault, ...)
*asynchronous*: indépendant du code, interruption qui vient de l'exterieur (appuyer sur une touche du clavier, problème hardware, ...)
On peut voir ça comme "synchronisé avec l'exécution d'une instruction"
**User mode** can access user space only
**Kernel mode** can access both user space and kernel space
Trap handler table: contient les routines à suivre pour chaque interruption
Syscalls:
- execute process, exit
- read input, write ouput, ...
- perform restricted actions (accessing hardware devices or the MMU)
- ...
Processor modes to ensure process isolation: user mode (user applications) / supervisor mode (system kernel operations)
On peut voir les syscalls comme des moyens d'accéder aux services que le kernel met à notre disposition (comme une grosse API)

Faults:
- conséquence de l'exécution de certaines instructions
- kernel exception handler may return to faulty user context
- syscalls are deliberate, faults are unexpected (et pas voulues)
To handle a fault, the OS can:
- kill user process
- notify process about the fault so it may resolve it itself
- solve the problem and resume transparently

To perform **multitasking**, OS has to:
- create and delete processes
- organize processes in memory
- schedule processes for CPU use
The idea is simulationg execution of concurrent execution of many processes as one may not use system ressources at full capacity

Important:
