---
# System prepended metadata

title: Cours ASM

---

# 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

![](https://i.imgur.com/zGEF9ZP.png)


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

![](https://i.imgur.com/PgVphkZ.png)

=> 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

![](https://i.imgur.com/OAPipzd.png)

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

![](https://i.imgur.com/VtY3SBq.png)

= 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)

![](https://i.imgur.com/NvPzoj8.png)

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

![](https://i.imgur.com/Tj7GaBO.png)

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

![](https://i.imgur.com/LUYW3F5.png)

Important:

![](https://i.imgur.com/5vGCw8g.png)