Bonjour à tous,
je suis un cours de compiler design dans lequel on doit créer un compilateur de a à z.
Le langage à implémenter est un sous-set de C.
La cible principale du langage est l'architecture x86-64.
Je n'ai malheureusement pas beaucoup de connaissances en assembleur et ça me pose pas mal de problèmes par ailleurs. En voici un pour lequel je ne comprends pas l'erreur :
Le code original est bêtement :
que mon compilateur traduit en assembleur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 int main() { int x1; x1 = 80; x1 /= 3; // 26 x1 *= 4; // 104 x1 -= 4; // 100 x1 += -17; // 83 x1 %= 10; // 3 return x1; }
Le problème semble venir de la division que j'effectue (deux fois).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 .section .text .type _start, @function .globl _start _start: pushq %rbp movq %rsp, %rbp movl $80, %eax movl $3, %edx cltd idivl %edx imull $4, %eax subl $4, %eax addl $-17, %eax movl $10, %edx cltd idivl %edx movl %edx, %eax leave ret .size _start, .-_start
L'erreur à l'exécution est :
Que fais-je de faux ?14880 Floating point exception(core dumped) ./a.out 2>&1 >a.result
Execution of binary unexpectedly failed with exception 8.
La valeur retournée devrait être 3 à la fin, mais le programme ne s'exécute pas jusqu'à la fin : il lève cette exception avant.
En passant, j'ai trouvé l'ABI d'AMD64, mais c'est affreux à lire, et ça sous-entend qu'on connaît déjà toutes les informations à propos de l'assembleur x86 32bits... avez-vous des ressources plus intéressantes pour comprendre comment faire telle ou telle opération en assembleur ?
Ajout : à noter que toutes les opérations sont à effectuer sur des entiers signés 32bits, soit de -2^31 à 2^31-1. La multiplication et la division (ainsi que le modulo) sont signés. Les opérations sont toutes des opérations entières.
Les under-overflows par additions/soustraction/multiplication ne doivent pas lever d'exception (à la place, on utilise la modulo 2^32.
e.g. -(2^31)=>-(-2^31)=>2^31=>-2^31
e.g. -2^31-1=>2^31-1
Les seules exceptions qui doivent être levées sont lors des divisions / modulos :
1. si on divise par zero
2. si le signe de la division cause un overflow (-2^31 / -1, ou -2^31%-1)
Partager