archi:index
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
archi:index [2016/02/13 06:51] – [Les tableaux] orel | archi:index [2024/03/18 15:06] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Architecture des Ordinateurs ====== | ====== Architecture des Ordinateurs ====== | ||
+ | * __Supports__ : http:// | ||
+ | * __UE__ : 4TIN304U (6ECTS) | ||
- | __Supports__ : http:// | + | ====Quelques Notes de TD==== |
- | + | ||
- | + | ||
- | __ Emploi du Temps__ : [[ http:// | + | |
- | + | ||
- | ===== Assembleur y86 ===== | + | |
- | + | ||
- | y86 est un langage assembleur simplifié basé sur l' | + | |
- | + | ||
- | Le y86 utilise 8 registres généraux | + | |
- | * %eax : le registre d' | + | |
- | * %ecx : le registre de compteur utilisé dans les boucles | + | |
- | * %edx : un registre auxiliaire | + | |
- | * %ebx : le registre //base index// utilisé comme pointeur sur la base d'un tableau | + | |
- | * %esp : le registre //stack pointer// qui pointe sur le sommet du cadre d' | + | |
- | * %ebp : le registre //frame base pointer// qui pointe la base du cadre d' | + | |
- | * %esi : le registre //source index// utilisé lors des copies de suite d' | + | |
- | * %edi : le registre // | + | |
- | + | ||
- | En outre, le registre %eip (// | + | |
- | + | ||
- | ==== If then ==== | + | |
- | + | ||
- | Pour effectuer un branchement conditionnel qui dépend d'un test entre deux registres %eax et %ebx, on commence typiquement à comparer ces deux registres par soustraction, | + | |
- | + | ||
- | <code c> | + | |
- | long a = 2, b = 3, c; | + | |
- | if (a < b) c = 1; | + | |
- | </ | + | |
- | + | ||
- | <code - ifthen.ys> | + | |
- | .pos 0 | + | |
- | mrmovl a,%eax | + | |
- | mrmovl b,%ebx | + | |
- | subl %ebx, | + | |
- | jge endif # on teste la condition de sortie : a-b >= 0 ? | + | |
- | then: | + | |
- | rmmovl %ecx,c # c = 1 | + | |
- | endif: | + | |
- | + | ||
- | .pos 0x100 | + | |
- | a: .long 2 | + | |
- | b: .long 3 | + | |
- | c: .long 0 | + | |
- | </ | + | |
- | + | ||
- | __Astuce__ : L' | + | |
- | + | ||
- | ==== If then Else ==== | + | |
- | + | ||
- | <code c> | + | |
- | long a = 2, b = 3, c; | + | |
- | if (b <= a) c = 1; else c = 2; | + | |
- | </ | + | |
- | + | ||
- | <code - ifthenelse.ys> | + | |
- | .pos 0 | + | |
- | mrmovl a,%eax | + | |
- | mrmovl b,%ebx | + | |
- | subl %eax, | + | |
- | jg else | + | |
- | then: | + | |
- | rmmovl %ecx,c # c = 1 | + | |
- | jmp endif | + | |
- | else: | + | |
- | rmmovl %ecx,c # c = 2 | + | |
- | endif: | + | |
- | + | ||
- | .pos 0x100 | + | |
- | a: .long 2 | + | |
- | b: .long 3 | + | |
- | c: .long 0 | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | ==== Boucle For ==== | + | |
- | + | ||
- | <code c> | + | |
- | long sum = 0; | + | |
- | for(i = 1 ; i <= 10 ; i++) sum += i; | + | |
- | </ | + | |
- | + | ||
- | <code - sum.ys> | + | |
- | .pos 0 | + | |
- | mrmovl sum,%edx # %edx: sum | + | |
- | irmovl 1,%eax # %eax: i = 1 | + | |
- | + | ||
- | loop: | + | |
- | isubl 10,%ebx # on calcule i-10 | + | |
- | jg end # condition arrêt si i-10 > 0 | + | |
- | addl %eax, | + | |
- | iaddl 1,%eax # i++ | + | |
- | jmp loop | + | |
- | end: rmmovl %edx,sum | + | |
- | halt | + | |
- | + | ||
- | .pos 0x100 | + | |
- | sum: .long 0 | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | __Note Bene__ : On peut un peu simplifier ce code en parcourant la boucle à l' | + | |
- | + | ||
- | ==== Pointeurs ==== | + | |
- | + | ||
- | + | ||
- | <code c> | + | |
- | long a = 1, b = 0; | + | |
- | long * p = &a; | + | |
- | b = *p; /* b = 1 */ | + | |
- | *p = 2; /* a = 2 */ | + | |
- | </ | + | |
- | + | ||
- | Dans le code suivant, on utilisera le registre %esi pour désigner le pointeur p. | + | |
- | + | ||
- | < | + | |
- | irmovl a, | + | |
- | mrmovl (%esi), | + | |
- | rmmovl %eax, | + | |
- | irmovl 2,%eax # *p = 2 | + | |
- | rmmovl %eax, | + | |
- | + | ||
- | .pos 0x100 | + | |
- | a: .long 1 | + | |
- | b: .long 0 | + | |
- | </ | + | |
- | + | ||
- | ==== Les tableaux ==== | + | |
- | + | ||
- | On rappelle que l' | + | |
- | + | ||
- | < | + | |
- | irmovl t, | + | |
- | mrmovl (%ebx), | + | |
- | ... | + | |
- | rmmovl %ecx, | + | |
- | rmmovl %ecx, | + | |
- | + | ||
- | .pos 0x100 | + | |
- | t: .long 1 # tableau t d' | + | |
- | .long 2 | + | |
- | .long 3 | + | |
- | .long 4 | + | |
- | </ | + | |
- | + | ||
- | //expliquer la variante d' | + | |
- | + | ||
- | ==== Décalage des valeurs dans un tableau ==== | + | |
- | + | ||
- | <code c> | + | |
- | for(i = 0 ; i < n-1; i++) | + | |
- | t[i] = t[i+1]; | + | |
- | </ | + | |
- | + | ||
- | <code - decalage.ys> | + | |
- | .pos 0 | + | |
- | + | ||
- | mrmovl n,%ecx | + | |
- | irmovl t,%ebx | + | |
- | + | ||
- | loop: isubl 1,%ecx # n-- | + | |
- | je end | + | |
- | mrmovl 4(%ebx), | + | |
- | rmmovl %eax, | + | |
- | iaddl 4,%ebx # t += 4 | + | |
- | jmp loop | + | |
- | + | ||
- | end: halt | + | |
- | + | ||
- | .pos 0x100 | + | |
- | n: .long 5 | + | |
- | t: .long 1 | + | |
- | .long 2 | + | |
- | .long 3 | + | |
- | .long 4 | + | |
- | .long 5 | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | ==== Appel de fonction et Pile ==== | + | |
- | + | ||
- | <code c> | + | |
- | long f(long i, long j) { return (i+j); } | + | |
- | long a = f(1,2); | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | <code - function.ys> | + | |
- | .pos 0 | + | |
- | irmovl stack, | + | |
- | jmp main | + | |
- | + | ||
- | f: mrmovl 4(%esp), | + | |
- | mrmovl 8(%esp), | + | |
- | addl %ecx, | + | |
- | ret | + | |
- | + | ||
- | main: | + | |
- | pushl %eax | + | |
- | mrmovl a,%eax | + | |
- | pushl %eax | + | |
- | call f # appel de la fonction f() | + | |
- | aret: popl %ecx # on dépile les 2 paramètres avec popl | + | |
- | popl %ecx # ou iaddl 8,%esp | + | |
- | rmmovl %eax, | + | |
- | halt | + | |
- | + | ||
- | .pos 0x100 | + | |
- | a: .long 1 | + | |
- | b: .long 2 | + | |
- | res: .long 0 | + | |
- | + | ||
- | .pos 0x200 # adresse de base de la pile | + | |
- | stack: | + | |
- | + | ||
- | </ | + | |
- | + | ||
- | + | ||
- | Tout d' | + | |
- | + | ||
- | + | ||
- | Avant l' | + | |
- | + | ||
- | Par convention, on place la valeur de retour de la fonction dans le registre //%eax//. | + | |
- | + | ||
- | __Nota Bene__ : Il ne faut pas oublier d' | + | |
- | + | ||
- | ==== Sauvegarde des registres lors d'un appel de fonction ===== | + | |
- | + | ||
- | Lors d'un appel de fonction, certains registres utilisés par l' | + | |
- | * les registres // | + | |
- | * les registres // | + | |
- | + | ||
- | <code - > | + | |
- | + | ||
- | + | ||
- | main: # sauvegarde des registres caller | + | |
- | pushl %eax | + | |
- | pushl %ecx | + | |
- | pushl %edx | + | |
- | # empilement des paramètres de f | + | |
- | ... | + | |
- | call f | + | |
- | # dépilement des paramètres de f | + | |
- | ... | + | |
- | # restauration des registres caller | + | |
- | popl %edx | + | |
- | popl %ecx | + | |
- | popl %eax | + | |
- | halt | + | |
- | + | ||
- | f: # récupération des paramètres | + | |
- | ... | + | |
- | # sauvegarde des registres callee | + | |
- | pushl %ebp | + | |
- | pushl %esi | + | |
- | pushl %edi | + | |
- | pushl %ebx | + | |
- | ... | + | |
- | ... | + | |
- | ... | + | |
- | # restauration des registres callee | + | |
- | popl %ebx | + | |
- | popl %edi | + | |
- | popl %esi | + | |
- | popl %ebp | + | |
- | ret | + | |
- | + | ||
- | </ | + | |
- | + | ||
- | __Nota Bene__ : En pratique, on sauvegardera uniquement les registres utiles pour éviter d' | + | |
- | + | ||
- | ==== Appel de fonction avec des variables locales ==== | + | |
- | + | ||
- | Les variables locales sont définies dans la pile après l' | + | |
- | + | ||
- | + | ||
- | <code - funcloc.ys> | + | |
- | .pos 0 | + | |
- | main: | + | |
- | mrmovl b, | + | |
- | pushl %eax | + | |
- | mrmovl a,%eax # on empile le premier param a | + | |
- | pushl %eax | + | |
- | call f # appel de la fonction f() | + | |
- | aret: popl %ecx # on depile le premier param | + | |
- | popl %ecx # on depile le second param | + | |
- | rmmovl %eax, | + | |
- | halt | + | |
- | + | ||
- | f: isubl 4,%esp # alloc variable locale x sur la pile | + | |
- | mrmovl 8(%esp), | + | |
- | mrmovl 12(%esp), | + | |
- | ... # compute x | + | |
- | mrmovl (%esp), | + | |
- | pushl %ecx # save x | + | |
- | ... # do something else | + | |
- | mrmovl (%esp), | + | |
- | iaddl 4,%esp # liberation variable locale x | + | |
- | ret | + | |
- | + | ||
- | .pos 0x100 | + | |
- | a: .long 1 | + | |
- | b: .long 1 | + | |
- | res: .long 0 | + | |
- | + | ||
- | .pos 0x200 # adresse de base de la pile | + | |
- | stack: | + | |
- | </ | + | |
- | + | ||
- | __Nota Bene__ : Dans un soucis de simplification, | + | |
- | + | ||
- | + | ||
- | ====Passage par référence dans les fonctions ==== | + | |
- | + | ||
- | Dans les exemples précédent de fonction, nous avons utiliser le //passage de paramètres par valleur// | + | |
- | Ici, nous donnons l' | + | |
- | + | ||
- | + | ||
- | <code - swap.ys> | + | |
- | .pos 0 | + | |
- | main: | + | |
- | irmovl b,%eax | + | |
- | pushl %eax # empiler &b | + | |
- | irmovl a,%eax | + | |
- | pushl %eax # empiler &a | + | |
- | call swap | + | |
- | iaddl 8,%esp # depiler | + | |
- | halt | + | |
- | + | ||
- | swap: | + | |
- | mrmovl 8(%esp), | + | |
- | mrmovl (%eax), | + | |
- | mrmovl (%ebx), | + | |
- | rmmovl %ecx, | + | |
- | rmmovl %edx, | + | |
- | ret | + | |
- | + | ||
- | .pos 0x100 | + | |
- | a: .long 1 | + | |
- | b: .long 2 | + | |
- | + | ||
- | .pos 0x200 | + | |
- | stack: | + | |
- | </ | + | |
- | + | ||
- | ==== Fonction manipulant un tableau ==== | + | |
- | + | ||
- | //todo// | + | |
- | + | ||
- | ==== Appel récursif de fonction ==== | + | |
- | + | ||
- | <code c> | + | |
- | f(n) { if(n == 0) return 0 ; else return (f(n-1)+n) ; } | + | |
- | main() { res = f(10); } | + | |
- | </ | + | |
- | + | ||
- | <code - recursif.ys> | + | |
- | .pos 0 | + | |
- | main: | + | |
- | mrmovl n,%eax | + | |
- | pushl %eax # empiler param n | + | |
- | call f | + | |
- | iaddl 4,%esp # depiler param | + | |
- | rmmovl %eax,res # resultat dans %eax | + | |
- | halt | + | |
- | + | ||
- | f: mrmovl 4(%esp), | + | |
- | andl %ecx, | + | |
- | je f0 # si n = 0 ? | + | |
- | fn: isubl 1,%ecx # n-1 | + | |
- | pushl %ecx # empiler param n-1 | + | |
- | call f # retour dans %eax | + | |
- | iaddl 4,%esp # depiler param | + | |
- | mrmovl 4(%esp), | + | |
- | addl %ecx, | + | |
- | ret | + | |
- | f0: irmovl 0,%eax | + | |
- | ret # valeur de retour dans %eax | + | |
- | + | ||
- | + | ||
- | end: halt | + | |
- | + | ||
- | .pos 0x100 | + | |
- | n: .long 10 | + | |
- | res: .long 0 # res = 55 = 0x37 | + | |
- | + | ||
- | + | ||
- | .pos 0x200 | + | |
- | stack: | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | ==== Structure Liste Chaînée ==== | + | |
- | + | ||
- | <code c> | + | |
- | struct list { | + | |
- | long x; | + | |
- | struct list * next; | + | |
- | }; | + | |
- | + | ||
- | long length(struct list * l) { | + | |
- | long n = 0; | + | |
- | while(l) { n++; l = l->next; } | + | |
- | return n; | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | <code - linkedlist.ys> | + | |
- | main: .pos 0 | + | |
- | irmovl stack, | + | |
- | irmovl l1,%eax | + | |
- | pushl %eax | + | |
- | call length | + | |
- | iaddl 4,%esp | + | |
- | halt | + | |
- | + | ||
- | length: mrmovl 4(%esp), | + | |
- | xorl %eax, | + | |
- | loop: andl %esi, | + | |
- | je end | + | |
- | iaddl 1, | + | |
- | mrmovl 4(%esi), | + | |
- | jmp loop | + | |
- | end: ret # retour n dans eax | + | |
- | + | ||
- | .pos 0x100 # linked list | + | |
- | l1: .long 1 | + | |
- | .long l2 # next = l2 | + | |
- | l2: .long 2 | + | |
- | .long l3 # next = l1 | + | |
- | l3: .long 3 | + | |
- | .long 0 # next = NULL | + | |
- | .pos 0x200 | + | |
- | stack: | + | |
- | </ | + | |
+ | * [[archi:y86 | Assembleur y86]] | ||
+ | * [[archi:x86 | Un peu de x86]] | ||
+ | * [[archi: | ||
+ | * [[archi: | ||
archi/index.1455346289.txt.gz · Last modified: 2024/03/18 15:05 (external edit)