もうちょっとアセンブリを読んでサンクを知ろう。

hac::Int->Int
hac a=a+1
とhac a=a+2
アセンブリのdiffを確かめる。
ghc -S test.hs
ghc -S test2.hs

diff test.s test2.hs

29c29< movl $stg_INTLIKE_closure+137,0(%ebp)

    • -

> movl $stg_INTLIKE_closure+145,0(%ebp)


……137ってなに…?
145-137=8
2word分遠いポインタをさしてる?

ちなみにa+3では153、a+(-1)では
15a16,34
> .long Hac_hac_srt-(skI_info)+0
> .long 0
> .long 65552
> skI_info:
> .LckX:
> leal -20(%ebp),%eax
> cmpl 84(%ebx),%eax
> jb .LckZ
> movl $stg_upd_frame_info,-8(%ebp)
> movl %esi,-4(%ebp)
> movl $stg_INTLIKE_closure+137,-12(%ebp)
> movl $stg_ap_p_info,-16(%ebp)
> movl $base_GHCziNum_zdfNumInt_closure,-20(%ebp)
> addl $-20,%ebp
> jmp base_GHCziNum_negate_info
> .LckZ:
> jmp *-8(%ebx)
> .text
> .align 4,0x90
23c42< .LckR:

    • -

> .Lcl8:
26c45,49< jb .LckU

    • -

> jb .Lcla
> addl $8,%edi
> cmpl 92(%ebx),%edi
> ja .Lclc
> movl $skI_info,-4(%edi)
29c52,53< movl $stg_INTLIKE_closure+145,0(%ebp)

    • -

> leal -4(%edi),%eax
> movl %eax,0(%ebp)
34c58,60< .LckU:

    • -

> .Lclc:
> movl $8,112(%ebx)
> .Lcla:
46c72< .Lcl7:

    • -

> .Lclq:
48,49c74,75< jne .Lcl8< .Lcl9:

    • -

> jne .Lclr
> .Lcls:
さらに、
hac a=a-1と、a=a+(-1)を比較すると、
15a16,34
> .long Hac_hac_srt-(skI_info)+0
> .long 0
> .long 65552
> skI_info:
> .LckX:
> leal -20(%ebp),%eax
> cmpl 84(%ebx),%eax
> jb .LckZ
> movl $stg_upd_frame_info,-8(%ebp)
> movl %esi,-4(%ebp)
> movl $stg_INTLIKE_closure+137,-12(%ebp)
> movl $stg_ap_p_info,-16(%ebp)
> movl $base_GHCziNum_zdfNumInt_closure,-20(%ebp)
> addl $-20,%ebp
> jmp base_GHCziNum_negate_info
> .LckZ:
> jmp *-8(%ebx)
> .text
> .align 4,0x90
23c42< .LckR:

    • -

> .Lcl8:
26c45,49< jb .LckU

    • -

> jb .Lcla
> addl $8,%edi
> cmpl 92(%ebx),%edi
> ja .Lclc
> movl $skI_info,-4(%edi)
29c52,53< movl $stg_INTLIKE_closure+137,0(%ebp)

    • -

> leal -4(%edi),%eax
> movl %eax,0(%ebp)
33,34c57,60< jmp base_GHCziNum_zm_info< .LckU:

    • -

> jmp base_GHCziNum_zp_info
> .Lclc:
> movl $8,112(%ebx)
> .Lcla:
46c72< .Lcl7:

    • -

> .Lclq:
48,49c74,75< jne .Lcl8< .Lcl9:

    • -

> jne .Lclr
> .Lcls:

こんな違いがあった。そこでわかったことは、整数値すらベタ書きではないということだ。
たとえば、1をとってくるには、
ある値をstg_INTLIKE_closure+145からとってきて、スタックに詰み、引数としていて、
それはその後のjmp base_GHCziNum_negate_infoしていることから、この関数?から値(1)を返して貰っているのだろうと推測できる。
そこで、*_infoは関数、closureはポインタなんじゃね?と考えることもできる。
でもすると
> movl $stg_ap_p_info,-16(%ebp)
ってなんだろ?

さらに、
33c57< jmp base_GHCziNum_zm_info

    • -

> jmp base_GHCziNum_zp_info
から、ziNum_zmは引き算、ziNum_zpは加算のサンクを積む関数であると推測できる。

さらに、2変数関数の場合はどうなるだろうか。
これを比べて、(+)関数のコールまえの引数の積み方を見よう。

hac::Int->Int->Int
hac a b=a+bに変えてdiff test.s(a+b) testint.s(a+1)
17c17< .long 131084

    • -

> .long 65541
23,24c23,24< .LckM:< leal -8(%ebp),%eax

    • -

> .LckS:
> leal -12(%ebp),%eax
26,29c26,32< jb .LckP< movl $stg_ap_pp_info,-4(%ebp)< movl $base_GHCziNum_zdfNumInt_closure,-8(%ebp)< addl $-8,%ebp

    • -

> jb .LckV
> movl 0(%ebp),%eax
> movl %eax,-4(%ebp)
> movl $stg_INTLIKE_closure+137,0(%ebp)
> movl $stg_ap_pp_info,-8(%ebp)
> movl $base_GHCziNum_zdfNumInt_closure,-12(%ebp)
> addl $-12,%ebp
31c34< .LckP:

    • -

> .LckV:
43c46< .Lcl1:

    • -

> .Lcl8:
45,46c48,49< jne .Lcl2< .Lcl3:

    • -

> jne .Lcl9
> .Lcla:
50c53< .Lcl2:

    • -

> .Lcl9:
58c61< .Lcl9:

    • -

> .Lclg:
わからないのは、
jmp base_GHCziNum_zp_info
とか
jmp *-4(%ebx)
とかなんだよな