LoginSignup
5
2

More than 5 years have passed since last update.

Crystalとnasmで作った静的リンクライブラリをリンクする

Posted at

こんにちは、Crystal界のわるいオタクです。

Crystalみたいな低レイヤを直に触れる言語だとちょくちょくインラインアセンブラを触りたくなることもあるかと思いますが、 OutputOperands に複数指定しようとするとなんだか構文エラーになってしまいます。

% crystal inlineasm.cr
Syntax error in inlineasm.cr:5: expecting token ')', not ':'

       : "={eax}"(low), "={edx}"(high)

しょうがないのでassemblyを書いてリンクすることで回避する方法でやってみましょう。C言語で書いた静的リンクライブラリでも同じようにできるはずです。

環境は

% cat /proc/version
Linux version 3.10.0-229.14.1.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC) ) #1 SMP Tue Sep 15 15:05:51 UTC 2015
% lsb_release -ds
"CentOS Linux release 7.1.1503 (Core) "
% crystal --version
Crystal 0.20.0 [b0cc6f7] (2016-11-22)

というかんじです。

まずAssembly側のコードを用意してやります。題材はrdtsc命令にします。

bits 64

global get_rdtsc

section .text

        ;; fun get_rdtsc(Void*)
get_rdtsc:
        rdtsc
        mov [rdi], eax
        mov [rdi + 4], edx
        ret

静的リンクライブラリを作りましょう。私の環境はLinuxなので nasm -f elf64 -o rdtsc.o rdtsc.asm && ar r librdtsc.a rdtsc.o という形で作っておきます。

次にcrystal側のコードです。

@[Link("rdtsc")]
lib LibRDTSC
  fun rdtsc = get_rdtsc(Void*)
end

zero = 0_u64
start = pointerof(zero)
LibRDTSC.rdtsc(start)
puts start.value
sleep(1)
fin = pointerof(zero)
LibRDTSC.rdtsc(fin)
puts fin.value

@Link(hoge) を指定するとリンカに -lhoge を渡してくれます。 (ドキュメント: https://crystal-lang.org/docs/syntax_and_semantics/c_bindings/lib.html)

$ crystal build --link-flags -L`pwd` rdtsc.cr

なんだかよくわからないけどちゃんと動いてるようにみえます。やったぜ。

% ./rdtsc
24892339598719468
24892342269338124
5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2