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

Documents pareils