Académique Documents
Professionnel Documents
Culture Documents
Cours 05
Cours 05
TEXT
main:
call fct1
call fct2
call fct1
ret
fct2:
ret
main:
Les appels de fonction call fct1
sont des branchements call fct2
call fct1
ret Le programme
sait où il faut
fct2: aller grâce à
ret l’étiquette
main:
call fct1
call fct2
call fct1
main:
call fct1
call fct2
call fct1
main:
call fct1
Deux options sont call fct2
possibles dans cet call fct1
exemple
0x3000 fct2:
ret esp 0xEF04
0x3FFC
esp
PILE 0x4000 main: add … eip
0x4004 call fct1
eip 0x4000
0x4008 call fct2
0x400C call fct1
0x4010
0x3000 fct2:
0x4008 ret esp 0xEF00
esp 0x3FFC
0x3000 fct2:
0x4008 ret esp 0xEF00
esp 0x3FFC
0x3000 fct2:
0x4008 ret esp 0xEF00
esp 0x3FFC
0x3000 fct2:
0x4008 ret esp 0xEF04
0x3FFC
esp
PILE 0x4000 main: add …
0x4004 call fct1
eip 0x4008
0x4008 call fct2 eip
0x400C call fct1
0x4010
0x3000 fct2:
0x400C ret esp 0xEF00
esp 0x3FFC
0x3000 fct2:
0x400C ret eip esp 0xEF00
esp 0x3FFC
0x3000 fct2:
0x400C ret esp 0xEF04
0x3FFC
esp
PILE 0x4000 main: add …
0x4004 call fct1
eip 0x400C
0x4008 call fct2
0x400C call fct1 eip
0x4010
0x3000 fct2:
esp 0x4010 ret esp 0xEF00
0x3FFC
0x3000 fct2:
esp 0x4010 ret esp 0xEF00
0x3FFC
0x3000 fct2:
esp 0x4010 ret esp 0xEF00
0x3FFC
0x3000 fct2:
0x4010 ret esp 0xEF04
0x3FFC
esp
PILE 0x4000 main: add …
0x4004 call fct1
eip 0x4010
0x4008 call fct2
0x400C call fct1
0x4010 eip
appelée
# Prologue # Epilogue
pushl %ebp movl %ebp, %esp Old ebp esp ebp
movl %esp, %ebp popl %ebp Return addr.
appelante
# Epilogue alt. 1e paramètre ebp + 8
leave
Appelée (MyFunc)
Exemple illustratif ‘Z’
-8(%ebp) %esp
int MyFunc(int parameter1, char parameter2) { -4(%ebp) 9
int local1 = 9; %ebp
Old %ebp
char local2 = ‘Z’; Ret addr
État de la pile quand on
Appelante (main)
return 0; est là 8(%ebp) 7
} 12(%ebp) ‘8’
12 0 jmp while_loop
bye:
ret
Exercices .text
.globl main
print_hex:
pushl 4(%esp)
pushl $hex
call printf
Exercice 1 addl
ret
main:
$8, %esp
pushl %esp
Soit le programme assembleur ci-contre. call print_hex
pushl $start_data
Sachant que les trois premiers appels à print_hex ont produit à call print_hex
0x0804A028 # 2
subl %eax, %eax
xorl %ebx, %ebx
Donnez le résultat des 3 affichages suivants ainsi que la ligne pushl start_data(%eax, %ebx, 1)
call print_hex
manquante en bas de la fonction.
# 3
pushl %esp
call print_hex
# 4
# Ligne volontairement masquée
ret
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 36
.data
start_data: .byte 0x12, 0x34, 0x56, 0x78
hex : .ascii "0x%08X\n\0"
end_data :
Exercices .text
.globl main
print_hex:
pushl 4(%esp)
pushl $hex
call printf
Exercice 1 addl
ret
main:
$8, %esp
pushl %esp
Soit le programme assembleur ci-contre. call print_hex
pushl $start_data
Sachant que les trois premiers appels à print_hex ont produit à call print_hex
0x0804A028 # 2
subl %eax, %eax
xorl %ebx, %ebx
Donnez le résultat des 3 affichages suivants ainsi que la ligne pushl start_data(%eax, %ebx, 1)
call print_hex
manquante en bas de la fonction.
# 3
pushl %esp
call print_hex
# 4
# Ligne volontairement masquée
ret
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 37
.data
start_data: .byte 0x12, 0x34, 0x56, 0x78
hex : .ascii "0x%08X\n\0"
end_data :
Exercices .text
.globl main
print_hex:
pushl 4(%esp)
pushl $hex
call printf
Exercice 1 addl
ret
main:
$8, %esp
pushl %esp
Soit le programme assembleur ci-contre. call print_hex
0x0804A028
pushl $start_data
Sachant que les trois premiers appels à print_hex ont produit à call print_hex - 0x0804A01C
l’écran ce qui suit: pushl $end_data
= 0x0000000C
call print_hex
0xBFC84C7C # 1
pushl $(end_data - start_data)
0x0804A01C call print_hex
0x0804A028 # 2
subl %eax, %eax
xorl %ebx, %ebx
Donnez le résultat des 3 affichages suivants ainsi que la ligne pushl start_data(%eax, %ebx, 1)
call print_hex
manquante en bas de la fonction.
# 3
pushl %esp
call print_hex
# 4
# Ligne volontairement masquée
ret
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 38
.data
start_data: .byte 0x12, 0x34, 0x56, 0x78
hex : .ascii "0x%08X\n\0"
end_data :
Exercices .text
.globl main
print_hex:
pushl 4(%esp)
pushl $hex
call printf
Exercice 1 addl
ret
main:
$8, %esp
pushl %esp
Soit le programme assembleur ci-contre. call print_hex
pushl $start_data
Sachant que les trois premiers appels à print_hex ont produit à call print_hex
0x0804A028 # 2
subl %eax, %eax
xorl %ebx, %ebx
Donnez le résultat des 3 affichages suivants ainsi que la ligne pushl start_data(%eax, %ebx, 1)
call print_hex
manquante en bas de la fonction.
# 3
pushl %esp
call print_hex
# 4
# Ligne volontairement masquée
ret
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 39
.data
start_data: .byte 0x12, 0x34, 0x56, 0x78
hex : .ascii "0x%08X\n\0"
end_data :
Exercices .text
.globl main
print_hex:
pushl 4(%esp)
pushl $hex
call printf
Exercice 1 addl
ret
main:
$8, %esp
pushl %esp
Soit le programme assembleur ci-contre. call print_hex
0x0804A028 # 2
subl %eax, %eax
xorl %ebx, %ebx
Donnez le résultat des 3 affichages suivants ainsi que la ligne pushl start_data(%eax, %ebx, 1)
call print_hex
manquante en bas de la fonction.
# 3
pushl %esp
call print_hex
# 4
# Ligne volontairement masquée
ret
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 40
.data
start_data: .byte 0x12, 0x34, 0x56, 0x78
hex : .ascii "0x%08X\n\0"
end_data :
Exercices .text
.globl main
print_hex:
pushl 4(%esp)
pushl $hex
call printf
Exercice 1 addl
ret
main:
$8, %esp
pushl %esp
Soit le programme assembleur ci-contre. call print_hex
0x0804A028 # 2
subl %eax, %eax
xorl %ebx, %ebx
Donnez le résultat des 3 affichages suivants ainsi que la ligne pushl start_data(%eax, %ebx, 1)
call print_hex
manquante en bas de la fonction.
# 3
pushl %esp
call print_hex
# 4
addl $0x18, %esp
ret
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 41
Exercices
Exercice 2
Donnez l’assembleur équivalent de la fonction suivante
int is_lower_case (const char c){
if ( c >= 'a' && c <= 'z')
return 1;
return 0;
}
Exercices .text
.globl is_lower_case
is_lower_case:
movb 4(%esp), %cl
unsigned int i = 0;
while(src[i] != 0)
i++;
return i;
}
Exercices .text
.globl length
length:
pushl %ebp
movl %esp, %ebp
Exercice 3
movl $0, %eax # %eax == i
Donnez l’assembleur équivalent de la fonction suivante movl 8(%ebp), %edx
end_loop:
return value;
}
Exercices .text
.globl to_integer
to_integer:
pushl %ebp
movl %esp, %ebp
jmp test
end_loop:
leave
ret
unsigned int i = 0, j = 0;
while( src[i] != 0 )
dst[j++] = src[i++];
dst[j] = '\0';
}
Exercices append:
movl 4(%esp), %ecx
Note:
# %ecx == dst
movl 8(%esp), %edx # %edx == src
L1:
Exercice 5 cmpb $0, (%ecx)
jz L2
Donnez l’assembleur équivalent de la fonction suivante incl %ecx
jmp L1
void append(char* dst, const char* src){
L2:
unsigned int i = 0, j = 0; cmpb $0, (%edx)
jz fin
while( dst[j] != 0 ) j++; movb (%edx), %al
movb %al, (%ecx)
while( src[i] != 0 ) incl %ecx
dst[j++] = src[i++]; incl %edx
jmp L2
dst[j] = '\0';
} fin:
movb $0, (%ecx)
ret
while( b != 0 ){
t = b;
b = a % b;
a = t;
}
return a;
}
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 50
.text
Exercice 6 movl
movl
8(%ebp), %eax
12(%ebp), %edx
Donnez l’assembleur équivalent de la fct suivante: T:
cmpl $0, %edx
unsigned int gcd(unsigned int a, jz L prologue
unsigned int b){
movl %edx, %ecx
unsigned int t; épilogue
movl $0, %edx
div %ecx
while( b != 0 ){
t = b; movl %ecx, %eax
b = a % b;
jmp T
a = t;
} L:
leave
return a; ret
}
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 51
.text
Exercice 6 movl
movl
8(%ebp), %eax
12(%ebp), %edx On va rechercher
les paramètres
Donnez un équivalent en assembleur IA-32 de la fonction
T:
suivante
b
cmpl $0, %edx
unsigned int gcd(unsigned int a, jz L
unsigned int b){
movl %edx, %ecx
unsigned int t;
movl $0, %edx
div %ecx
while( b != 0 ){
t = b; movl %ecx, %eax
b = a % b;
jmp T
a = t;
} L:
leave
return a; ret
}
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 52
.text
Exercice 6 movl
movl
8(%ebp), %eax
12(%ebp), %edx
Donnez un équivalent en assembleur IA-32 de la fonction suivante
while_loop:
cmpl $0, %edx
unsigned int gcd(unsigned int a, jz au_revoir
unsigned int b){
movl %edx, %ecx
unsigned int t;
movl $0, %edx
div %ecx
while( b != 0 ){
t = b; movl %ecx, %eax
b = a % b;
jmp while_loop
a = t;
} au_revoir:
leave
return a; ret
}
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 53
.text
Exercice 6 movl
movl
8(%ebp), %eax
12(%ebp), %edx
Donnez un équivalent en assembleur IA-32 de la fonction suivante
while_loop:
cmpl $0, %edx
unsigned int gcd(unsigned int a, jz au_revoir
unsigned int b){
movl %edx, %ecx
unsigned int t;
movl $0, %edx # %eax <- %eax / %ecx
div %ecx # %edx <- mod(%eax,%ecx)
while( b != 0 ){
t = b; movl %ecx, %eax
b = a % b;
jmp while_loop
a = t;
} au_revoir:
leave
return a; ret
}
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 54
.text
Exercice 6 movl
movl
8(%ebp), %eax
12(%ebp), %edx
Donnez un équivalent en assembleur IA-32 de la fonction suivante
while_loop:
cmpl $0, %edx
unsigned int gcd(unsigned int a, jz au_revoir
unsigned int b){
movl %edx, %ecx
unsigned int t;
movl $0, %edx
div %ecx
while( b != 0 ){
t = b; movl %ecx, %eax
b = a % b;
jmp while_loop
a = t;
} au_revoir:
leave
return a; ret
}
Mise à jour: 2022/02/09 INF1600: Architecture des micro-ordinateurs 55
Exercices
Exercice 7
Écrivez la fonction suivante en assembleur:
Unsigned int count_steps(unsigned int n){
while( n > 1 ){
steps = steps + 1
if ( n % 2 == 0 )
n = n/2;
else
n = 3*n + 1;
}
return steps
}
Exercice 7 Réponse….
while( n > 1 ){
steps = steps + 1
… # On va construire la boucle
if ( n % 2 == 0 )
n = n/2;
else
n = 3*n + 1;
}
return steps
}
# resultat (steps) est dans %eax
return steps
Fin_boucle: }
jmp Test # Teste si necessaire de boucler
Fin: # resultat (steps) est dans %eax
On incrément steps if ( n % 2 == 0 )
n = n/2;
else
n = 3*n + 1;
}
return steps
}
Fin_boucle: # Va vers Test
Fin: # resultat (steps) est dans %eax
while( n > 1 ){
steps = steps + 1
# test de parite
jnz Impair Structure if/else if ( n % 2 == 0 )
n = n/2;
# n = n/2 else
n = 3*n + 1;
jmp Fin_boucle }
return steps
}
return steps
}
return steps
}
return steps
}
return steps
}
return steps
}
return steps
}
return steps
}
return steps
}
int p = 0;
return 1;
}
Exercices .text
.globl is_prime
is_prime:
Note:
# %ebx == n
pushl %ebp
movl %esp, %ebp
pushl %ebx
Exercice 8
movl 8(%ebp), %ebx
Donnez l’assembleur équivalent de la fonction suivante
cmpl $0, %ebx
je not_prime
int is_prime(unsigned int n){
cmpl $1, %ebx Nous aurons plus loin…
int p = 0; je not_prime
prime:
cmpl $2, %ebx movl $1, %eax
for(; p<2; p++) if( n == p ) return 0; jmp bye
je prime
for(; p<4; p++) if( n == p ) return 1;
if( n % 2 ) return 0; cmpl $3, %ebx not_prime:
je prime movl $0, %eax
for(p = 3; p*p <= n; p += 2)
movl %ebx, %eax bye:
if( ( n % p ) == 0 ) popl %ebx
return 0; andl $1, %eax
cmpl $0, %eax leave
je not_prime ret
return 1;
}
Exercices movl
test:
$3, %ecx Note:
# %ebx == n
movl %ecx, %eax # %ecx == p
mul %ecx # %eax == p*p
if( a == 0 ) return b;