All asm codes are compiled in https://godbolt.org/, by x86-64 ocamlopt 5.2.0
.
let declaration
Let’s start from a simple example. A whole file is written with only two lines:
|
|
Compiled:
|
|
The value of the list is stored in segment.
The immediate value $21
is the value of a 10
, I guess that may bring some benefit for arithmetic (And 21 >> 1 == 10
).
The 3
in camlExample.3
is the 1
, and the 5
in camlExample.2
is the 2
.
I can see the linked list structure that there’s an address right after the integer data(and there’s a 1
as zero standing for the tail).
After get the address of the variables, it calls the function caml_initialize
, the 1st is caml_initialize(camlExample, 10)
and the 2nd is caml_initialize(camlExample+8, camlExample.3)
.
So I know the data in camlExample
stores the pointer of the variables.
The official doc also mentioned it.
I also see that it mov
a strange value %r14 + 64
to %rsp
to take place of previous %rsp
. This is not easy to explain. In short, OCaml compiler use Emulating Thread Local Storage tech in gcc to let the OCaml processes run as threads of C process, which causes the variable declaration caml_initialize
should use the main thread process stack address %r14 + 0x40
. It doesn’t matter and I can just ignore it(although I takes hours to make it up).
curry
Source code
|
|
Assembly
|
|
Because the interger in OCaml is OCamlnum == realnum * 2 + 1
, The leaq -1(%rax,%rbx), %rax
in camlExample.fun_342
is doing a plus operation. It’s my (fun acc x -> acc + x)
.
At here the official doc said %r15
is used as a heap pointer in my case:OCaml on x86_64 architectures caches the location of the minor heap in the %r15 register since it's so frequently referenced in OCaml functions.
It’s amazing that there’s two ways to curry a function. The first is the camlExample.4
, use a built-in function to curry my lambda function. Another is to build a sequence for a expression, and evaluate it.