Exercice 1 (Basic--). On consid`ere le langage Basic-
Transcription
Exercice 1 (Basic--). On consid`ere le langage Basic-
TD3 Exercice 1 (Basic--). On considère le langage Basic-- dont les programmes sont des suites d’instructions “basiques” inst1 , . . . , instl (chaque instruction a donc un numéro). On ne dispose que de deux variables entières x et y. Une instruction basique inst est au choix : — une affectation de la forme x ← e, ou y ← e, où e est une expression arithmétique, — un test ?x = 0, ou ?y = 0, qui a pour effet d’ignorer l’instruction suivante si la variable ne contient pas 0 — l’instruction push v qui met le contenu de la variable v (x, y, ou pc) sur la pile. Si v est pc, la valeur mise sur la pile est le numéro de l’instruction. — l’instruction pop v (x ou y) qui enlève de la pile l’entier n et le range dans v (si la pile est vide, v reçoit une valeur aléatoire) — l’instruction goto e qui passe à l’instruction instk si l’expression arithmétique e s’évalue en k. Un programme qui comporte l instructions termine lorsque l’on cherche à exécuter l’instruction l + 1. On note A(m, n) la fonction d’Ackermann, définie comme : si m = 0 n+1 A(m − 1, 1) si m > 0 et n = 0 A(m, n) = A(m − 1, A(m, n − 1))) si m > 0 et n > 0. Écrire un programme en Basic-- qui se termine avec la variable x qui contient A(m, n) lorsque initialement la variable x contenait m et la variable y contenait n. Exercice 2 (Instructions Pentium). On rappelle que l’instruction “movl e1 , e2 ” a pour effet d’écrire la valeur dénotée par e1 dans le conteneur (registre ou emplacement mémoire) dénoté par e2 . Les expressions e1 , e2 ont différent format, notamment : — le format “immédiat” : $0x12,$0xcafe,. . . — le format “registre” : %eax, %ebx,. . . — le format “absolu” : 0x12, 0xcafe,. . . — le format “indirect” : (%eax), %ebx,. . . — le format “indirect avec décalage” : 0xcafe(%eax), (%eax,%ebx, 4), . . . — le format “adresse d’un indirect avec décalage” : %0xcafe(%eax),. . . 1. L’instruction “leal e1 , e2 ” a pour effet d’écrire l’adresse du conteneur e1 dans le conteneur e2 . Quels sont les formats autorisés pour e1 et e2 ? 2. Lorsque e1 et e2 le permettent, réécrivez l’instruction “leal e1 , e2 ” à l’aide de movl Exercice 3 (Switch C). On considère la fonction C et sa traduction assembleur données à la page suivante. 1. On rappelle que le drapeau ZF (zero flag) est modifié par les instructions arithmétiques et lu par les instructions de branchement. Suivez dans le code assembleur le déroulement pas à pas de la fonction lorsque i=3 (Indication : on saute en LBB0 2). 2. Comment est renvoyé le résultat de la fonction ? Comment est passée la valeur initiale de la variable i ? Où la variable i est-elle stockée par la suite ? 3. Pour i = 0, quels sont les labels visités, et quelle est la valeur renvoyée ? 4. Même question pour i = 2. 5. Même question pour i = 1. 1 int f ( int i ){ switch ( i ) { case 1 : i ++; case 3 : return 3 ; default : { i −−; break ; } case 2 : return 2 ; } return 0 ; } 1 f: 3 4 5 6 7 8 9 10 11 pushq movq movl movl subl movl movl je jmp %rbp %rsp , %rbp %edi , −8(%rbp ) %edi , %eax $3 , %edi %eax , −12(%rbp ) %edi , −16(%rbp ) LBB0 2 LBB0 7 movl subl movl je jmp −12(%rbp ) , %eax $2 , %eax %eax , −20(%rbp ) LBB0 4 LBB0 8 LBB0 7 : 12 13 14 15 16 17 LBB0 1 : 23 2 19 21 22 26 −12(%rbp ) , %eax $1 , %eax %eax , −24(%rbp ) LBB0 3 LBB0 1 movl addl movl −8(%rbp ) , %eax $1 , %eax %eax , −8(%rbp ) movl jmp $3 , −4(%rbp ) LBB0 6 movl addl movl jmp −8(%rbp ) , %eax $0xFFFFFFFF , %eax %eax , −8(%rbp ) LBB0 5 movl jmp $2 , −4(%rbp ) LBB0 6 movl $0 , −4(%rbp ) movl popq retq −4(%rbp ) , %eax %rbp LBB0 2 : 27 28 29 LBB0 3 : 30 31 32 34 LBB0 4 : 35 36 37 LBB0 5 : 38 39 movl subl movl jne jmp 20 25 33 LBB0 8 : 18 24 LBB0 6 : 40 41 42 43 Exercice 4 (Fonctions). On considère la fonction C et sa traduction assembleur ci-dessous. i n t f ( i n t i , i n t j ) { return ( i ==0)? j : f ( i −1 , i ∗ j ) ; } 1 f: 14 pushq movq subq movl movl cmpl jne movl movl jmp 2 3 4 5 6 7 8 9 10 11 12 13 %rbp %rsp , %rbp $16 , %rsp %edi , −4(%rbp ) %e s i , −8(%rbp ) $0 , −4(%rbp ) LBB0 2 −8(%rbp ) , %eax %eax , −12(%rbp ) LBB0 3 LBB0 2 : 15 16 17 18 19 20 $1 , %eax −4(%rbp ) , %ecx −8(%rbp ) , %ecx %eax , %edi %ecx , %e s i f %eax , −12(%rbp ) movl addq popq retq −12(%rbp ) , %eax $16 , %rsp %rbp LBB0 3 : 21 22 23 24 25 movl subl movl imull movl movl callq movl −4(%rbp ) , %eax 1. Expliquez la différence entre cette fonction et la précédente quant au registre %rsp. 2. En vous inspirant des codes assembleurs ci-dessus, écrivez le code assembleur d’une fonction à un seul argument calculant la factorielle. 2