34 votes

Comprendre la sortie d'un assemblage GHC

Lors de la compilation d'un fichier source haskell à l'aide de l'option -S dans GHC, le code assembleur généré n'est pas clair. Il n'y a pas de distinction claire entre les parties du code d'assemblage qui appartiennent à quelles parties du code haskell. Contrairement à GCC, chaque étiquette est nommée en fonction de la fonction à laquelle elle correspond.

Y a-t-il une certaine convention dans ces noms produits par GHC? Comment puis-je associer certaines pièces du code d'assemblage généré à leurs pièces correspondantes dans le code haskell?

31voto

hammar Points 89293

De haut niveau des déclarations, il n'est pas trop dur. Les définitions locales peuvent être plus difficiles à reconnaître que leurs noms se déchire et qu'ils sont susceptibles d'être insérée.

Nous allons voir ce qui se passe lorsque nous compiler ce module simple.

module Example where

add :: Int -> Int -> Int
add x y = x + y
.data
    .align 8
.globl Example_add_closure
.type Example_add_closure, @object
Example_add_closure:
    .quad   Example_add_info
.text
    .align 8
    .quad   8589934604
    .quad   0
    .quad   15
.globl Example_add_info
.type Example_add_info, @object
Example_add_info:
.LckX:
    jmp base_GHCziBase_plusInt_info

Vous pouvez voir que notre fonction d' .data .align 8 _module_registered: .quad 0 .text .align 8 .globl __stginit_Example_ .type __stginit_Example_, @object __stginit_Example_: .Lcl7: cmpq $0,_module_registered jne .Lcl8 .Lcl9: movq $1,_module_registered addq $-8,%rbp movq $__stginit_base_Prelude_,(%rbp) .Lcl8: addq $8,%rbp jmp *-8(%rbp) .text .align 8 .globl __stginit_Example .type __stginit_Example, @object __stginit_Example: .Lcld: jmp __stginit_Example_ .section .note.GNU-stack,"",@progbits .ident "GHC 7.0.2" a abouti à la génération d' Example.add et Example_add_closure. L' Example_add_info partie, comme son nom l'indique, a à faire avec des fermetures. L' _closure partie contient les instructions de la fonction. Dans ce cas, c'est tout simplement un saut à la fonction intégrée _info.

Notez que l'assemblée généré à partir du code Haskell semble tout à fait différent de ce que vous pourriez obtenir à partir d'autres langues. Les conventions d'appel sont différents, et les choses peuvent être réorganisées beaucoup.

Dans la plupart des cas, vous ne voulez pas sauter directement à l'assemblée. Il est généralement beaucoup plus facile à comprendre de base, une version simplifiée de Haskell. (Plus simple pour compiler, pas nécessairement pour le lire). Pour aller au cœur, compilez avec l' GHC.Base.plusInt option.

-ddump-simpl

Pour quelques bonnes ressources sur la façon de lire de base, voir à cette question.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X