了解GHC汇编输出 [英] Understanding GHC assembly output

查看:154
本文介绍了了解GHC汇编输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当编译使用GHC大会code产生的-S选项一个Haskell源文件尚不清楚。有没有明确的区分这之间的装配code部分属于哪个Haskell的code的部分。不像GCC为每个标签是根据它对应于功能命名

When compiling a haskell source file using the -S option in GHC the assembly code generated is not clear. There's no clear distinction between which parts of the assembly code belong to which parts of the haskell code. Unlike GCC were each label is named according to the function it corresponds to.

有由GHC产生这些名字一定的约定?我如何能与在生成的汇编code某些部分其相应部位的哈斯克尔code?

Is there a certain convention in these names produced by GHC? How can I relate certain parts in the generated assembly code to their corresponding parts in the haskell code?

推荐答案

有关顶层的声明,这不是太辛苦。局部定义也很难承认他们的名字得到错位,他们可能得到内联。

For top level declarations, it's not too hard. Local definitions can be harder to recognize as their names get mangled and they are likely to get inlined.

让我们看到,当我们编译这个简单的模块会发生什么。

Let's see what happens when we compile this simple module.

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

You can see that our function Example.add resulted in the generation of Example_add_closure and Example_add_info. The _closure part, as the name suggests, has to do with closures. The _info part contains the actual instructions of the function. In this case, this is simply a jump to the built-in function GHC.Base.plusInt.

请注意从哈斯克尔code生成汇编看起来与你可能从其他语言中得到什么很大的不同。调用约定是不同的,事情可能会变得重新排序了不少。

Note that assembly generated from Haskell code looks quite different from what you might get from other languages. The calling conventions are different, and things can get reordered a lot.

在大多数情况下,你不希望直接跳到装配。它通常是很容易理解的核心的,哈斯克尔的简化版本。 (简单的编译,不一定要读)。为了获得为核心,以编译 -ddump-SIMPL 选项。

In most cases you don't want to jump straight to assembly. It is usually much easier to understand core, a simplified version of Haskell. (Simpler to compile, not necessarily to read). To get at the core, compile with the -ddump-simpl option.

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

有关如何阅读核心一些很好的资源,请参见这个问题

For some good resources on how to read core, see this question.

这篇关于了解GHC汇编输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆