Cours 2 : Architecture, Console, Assembleur

Intro : Suite

  • Entiers (machine) :
    • non signés : de $0$ à $2^n-1$
    • signés (complément à 2) : $-2^{n-1}$ à $2^{n-1}-1$
  • Caractères :
    • ASCII (VS : EBCDIC)
    • Unicode, UTF-8 (8 bits jusqu’à 4 octets)
      • ∃ aussi UTF-16 (16 bits par défaut), UTF-32 (caractères codés sur 32 bits)

Compiler un code en C avec debugger :

gcc -ggdb -O0 cat.c -o mycat

  • gcc : compilateur domaine public

Debugger : lldb mycat (OU : gdb)

(lldb) run a b

Sous UNIX : tout programme renvoie un code pour dire si l’exécution s’est bien passée (si code = 0 : pas de pb).

Lorsqu’on lance une commande : lance un processus (numéro du processus = Process Identification Number)

Attention : il y a des attaques qui se basent sur le numéro du processus suivant (donc sous Linux : numéro au hasard MAIS Mac : numéro = i+1)

En hexadécimal : préfixe = 0x

  • Ex:
    • décimal : 123
    • hexa : 0x7B
    • binaire : 01111011
    • octal : 0173 (préfixe : 0)

Pourquoi en hexadécimal ? 16 = 2^4 ⟶ demi-octet (notation compacte) On veut la représentation en binaire, MAIS : en binaire : trop verbeux (1 octet = 8 bits).

7       B
0111    1011

NB : ∃ octal ⟶ pq, alors que 8 pas multiple de 3 ?

  • Parce que : cf. permission (read - write/erase - execute)

    • d : directory / - : fichier normal
    • premier groupe : utilisateur
    • deuxième : groupe de l’utilisateur
    • troisième : autres personnes

Comme il y a 3 caractères (r-w-x) ⟶ octal

Changer les autorisations : chmod o -x myfichier : les autres (others)

OU : chmod 0755 myfichier

0755 : en octal


(lldb) b main ⟶ breakpoint main

C = Langage impératif :

  • Affectation :
    • C : x = e;, x[i] = e;
      • if (x == y+1) c1; else c2;
        • Attention : if (x = y+1) : une affectation est une expression, qui a une valeur (ex: 3; mais ne fait rien) ⟶ x=3 : met 3 dans x, et retourne 3
          • Pq retourne 3 ? Pour que x=y=3; soit possible

          En C : tout est un entier (suite de bits) ⟶ 0 = booléen false, n’importe quoi d’autre non nul = true

          Types : int = signed int, unsigned int, long int = long (= entiers signés au moins aussi larges que int (en pratique : 64bits))

          Sur une machine 64bits : int sur 32 bits

          short, unsigned short : sur 16bits

          char ⟶ seul type de donnée exactement sur 1octet, unsigned char, signed char

    • Pascal : x := e x[i]:= e : pourquoi := ? Inventeur du Pascal : “ce n’est pas l’égalité mathématique” ⟶ en informatique, il serait logique que le = soit réservé au test d’égalité.
      • Pascal : if x=y+1 then ... else ...

NB : 123 (qui loge sur 1octet) est un char

(char)123(char) : le “cast”, on force le type

p (char)123 (print …)

En ASCII : dans les 32 premiers codes ⟶ caractères de contrôle.

En UTF-8 : rétrocompatibilité (cf. wikipedia)

mycat a bargv tableau contenant

  • 0 → chemin absolu de mycat
  • 1 → a
  • 2 → b
  • 3 → NULL
  • 4 → variables d’environnement

argc : taille “officielle” (nb arguments + 1) de argv (=3 ici)

FILE *f; pointeur fichier

f = fopen(argv[i], "r")

fgetc(f) : obtenir le prochain caractère dans f

while ((c=fgetc(f)) != EOF) : parenthèses autour de c=fgetc(f) pour ne pas avoir de suggestion d’erreur “avez-vous confondu = et == ?”

EOF = End Of File : quand on arrive au bout du fichier, caractère spécial. Pour EOF :

  • MSDOS : reserve le code de ctrl-Z à la fin du fichier (vs: fichier exécutable : se termine autrement)
  • Unix : la fin de fichier = -1 = FF (= que des 1, en complément à deux VS 255 = 0⋯01⋯1), mais ne se loge pas sur un char = 8 bits. DONC c’est pour ça qu’on impose le type int à c

Pq fputc(c, stdout) n’affiche pas c tout de suite ? Parce que va dans un tampon : tableau de tous les caractères en attente d’affichage

⟶ puis : quand rempli OU quand on vide le tampon avec fflush(stdout);, affiche le contenu en faisant passer les instructions jusque dans le kernel.

  • \n : code 10 ⟶ saut à la ligne (sous Unix)
  • \t : tabulation
  • \r : code 13 ⟶ retour chariot ⟹ sous Windows : passage à la ligne : \r\n

Mémoire = un tableau d’octets (2^32 entrées ≃ 4.10^9)

Adresses = entiers ⟶ stockables en mémoire (adresses = pointeurs)

Micro-processeur (Micro : dans les années 70 ⟶ processeur réduit dans un circuit intégré) = processeur.

(1 coeur = 1 micro-processeur)

Mémoire + processeur ≃ Machine de Turing

Machine de Turing universelle : MT codée comme une structure arborescente ⟶ On peut lui donner un programme et des données en argument.

  • Avant : ordinateurs ne savaient faire qu’un truc
  • ≃ 1940 : Von Neumann : mieux que l’ordi soit une MT universelle

Convention de l’assembleur Intel : % = préfixe d’un registre $ = préfixe d’une constante entière

  • pc (program counter) ⟶ ‘eip’

Pourquoi les registres commencent par % et e ? À cause du premier Intel 4004 : 4 bits, 4 processeurs

  • Puis : Intel 8008 : 8 processeurs

IBM sort le Personal Computer pour concurrencer l’Apple2, Comodore, etc…

Pourquoi Intel a survécu ? Parce qu’IBM les a choisis (ils vendaient le processeur 16bit le moins cher).

  • ax, bx, etc… les registres 16 bits des anciennes versions a, b
  • eax : extended ax, … : les versions 32 bits

  • registre esp : pointeur de pile, mais se manipule comme un registre normal.

La mémoire ≃ un livre (de 4.10^9 pages) Les registres ≃ le crâne de l’utilisateur

On empile sur le sommet de pile, qui lui-même est en bas (=gauche).

  • Processeur Intel = Little Endian : stocke l’octet de poids faible d’abord, jusqu’à l’octet de poids fort (à l’envers, dans la pile)
  • Processeur Motorolla = Big Endian : stocke l’octet de poids fort d’abord, jusqu’à l’octet de poids faible (à l’endroit)

Endianness ⟶ Problèmes dans les protocoles réseau : ex: carte réseau reçoit les données en Little OU Big Endian ?

  • Système de fenêtrage : système X-window ⟶ on peut se connecter à distance sur notre machine et avoir des fenêtres.

Protocole X-Window : en quel Endian ?

  • Malin : le protocole cherche un compromis d’endianness entre le client et le serveur

Assembleur : mov esp ebp : copie esp dans ebp.

  • sub a b : soustrait b à a, valeur qui est stockée dans a

Modes d’adressage :

  • Mode registre : %eax : le contenu du registre eax
  • Mode immédiat : $114 : la constante 114
  • Mode absolu : 114 : contenu de la mémoire à l’adresse 114.
  • Mode indirect : (%eax) : contenu de la mémoire à l’adresse qui est la valeur de eax.
  • Mode indirect avec déplacement (=offset) :
    • 12(%eax) : contenu de la mémoire à l’adresse qui est la valeur de eax+12.
    • -12(%eax) : contenu de la mémoire à l’adresse qui est la valeur de eax-12.
    • 12(%eax,%ebx,4) (multiplicateur : 1,2,4 ou 8): contenu de la mémoire à l’adresse qui est la valeur de eax + 4*ebx - 12

En vrai : pas mov, mais movl (32 bits), movq (64 bits), movb (byte) …

Microprocesseur :

  • Avant ≃ employé de banque : chaque action prenait un cycle d’horloge (une instruction à la fois)
  • Maintenant ≃ employé super speed : donne des instructions à des factotum qui font les différentes instructions à plusieurs en même temps

  • Une personne par instruction = pipeline (lecture, décodage, exécution) : travail à la chaîne
  • Aujourd’hui : plusieurs instructions en parallèle, où chaque unité de calcul a ses propres “copies fantômes” des registres pour connaître les priorités.

VHDL (Langage de Hardware) ⟶ Autres langages plus proches du matériel (portes logiques, etc …) : ≃ 15 couches

  • rbp : équivalent de ebp, mais version 64 bits.

Que se passe-t-il en assembleur pour la boucle for ?

int main(int argc, char **argv)
{
int i, c;
for(i=1; i < argc; i++)
  {
    FILE *f;
  }
}

Leave a comment