ham*_*mar 29
对于顶级声明,它并不太难.本地定义可能更难以识别,因为它们的名称会被破坏,并且可能会被内联.
让我们看看编译这个简单模块时会发生什么.
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
.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"
你可以看到我们的函数Example.add导致了Example_add_closure和的生成Example_add_info._closure顾名思义,该部分与闭包有关.该_info部分包含该函数的实际指令.在这种情况下,这只是跳转到内置函数GHC.Base.plusInt.
请注意,从Haskell代码生成的程序集看起来与您从其他语言获得的程序集完全不同.调用约定是不同的,事情可以重新排序很多.
在大多数情况下,您不希望直接跳到装配体.通常更容易理解核心,Haskell的简化版本.(编译起来比较简单,不一定要阅读).要获得核心,请使用该-ddump-simpl选项进行编译.
Example.add :: GHC.Types.Int -> GHC.Types.Int -> GHC.Types.Int
[GblId, Arity=2]
Example.add =
  \ (x_abt :: GHC.Types.Int) (y_abu :: GHC.Types.Int) ->
    GHC.Num.+ @ GHC.Types.Int GHC.Num.$fNumInt x_abt y_abu
有关如何阅读核心的一些好资源,请参阅此问题.
| 归档时间: | 
 | 
| 查看次数: | 3916 次 | 
| 最近记录: |