Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Shinjuku.rs#15 Rustでつくるx86アセンブラ
Search
monochrome
April 27, 2021
Programming
0
1.5k
Shinjuku.rs#15 Rustでつくるx86アセンブラ
Making JIT assembler for x86-64 written in Rust.
monochrome
April 27, 2021
Tweet
Share
More Decks by monochrome
See All by monochrome
Running Optcarrot (faster) on my own Ruby.
sisshiki1969
0
26
仮想マシンにおけるスタックの管理
sisshiki1969
0
160
Rustでゴミ集め
sisshiki1969
1
260
RustでつくるRubyのFiber
sisshiki1969
0
220
fukuoka.rb#202 RustでつくるRuby
sisshiki1969
1
710
RustでつくるRubyのFiber
sisshiki1969
0
400
Rustでつくるガーベジコレクタ
sisshiki1969
0
570
Other Decks in Programming
See All in Programming
社内 LT 会を発足し、アウトプット文化を醸成させるために考えたこと・やったこと / Starting internal LT meetings and fostering an output culture
mackey0225
3
120
AWS CDKにおける「再利用性」を考える / aws-cdk-reusability
gotok365
6
1.3k
日付と正規化
megmogmog1965
0
140
君たちはどうコードをレビューする (される) か / 大吉祥寺.pm
utgwkk
15
8.5k
継続的な活動で築く地方エンジニアの道
myamashii
2
360
유연한 Composable 설계
l2hyunwoo
0
380
ピグパーティにおけるMongoDB CommunityバージョンからAtlasへの移行事例
10969hotaka
0
130
生成AIをkintoneに連携してみた
hideg
0
230
Jetpack for KMP
fornewid
1
290
Temporalを取り巻く仕様を整理する
sajikix
0
110
CSC307 Lecture 07
javiergs
PRO
0
220
小さな開発会社を作った理由
polidog
0
1.9k
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
360
22k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
24
1.8k
Gamification - CAS2011
davidbonilla
78
4.9k
Clear Off the Table
cherdarchuk
89
320k
In The Pink: A Labor of Love
frogandcode
139
22k
Practical Orchestrator
shlominoach
185
10k
A Modern Web Designer's Workflow
chriscoyier
689
190k
Faster Mobile Websites
deanohume
303
30k
How to name files
jennybc
67
96k
Docker and Python
trallard
37
2.9k
Web development in the modern age
philhawksworth
203
10k
The Cult of Friendly URLs
andyhume
75
5.9k
Transcript
Rustでつくるx86アセンブラ monochrome twitter: @s_isshiki1969 Slack: プログラミング言語処理系が好きな人の集まり https://prog-lang-sys-ja-slack.github.io/wiki/ monoasm: https://github.com/sisshiki1969/monoasm
アセンブラ is 何 int main() { return 42; } main:
push rbp mov rbp, rsp mov eax, 42 pop rbp ret 55 48 89 e5 b8 2a 00 00 00 5d c3 0f 1f 00 hoge.c hoge.s hoge.o これ アセンブリのテキストファイルを機械語へ変換
インラインアセンブラ in Rust let i: u64 = 3; let o:
u64; unsafe { asm!( "mov {0}, {1}", "add {0}, {number}", out(reg) o, in(reg) i, number = const 5, ); } 1. asmマクロのある位置に機械語を挿入 2. 変数や値を埋め込むことができる
ダイナミックアセンブラ • 「実行時に機械語を吐くコード」を生成するライブラリ • メモリ上に機械語を格納するバッファを確保し、実行中にそこへ機械語を 生成していく • 応用例としてはJITコンパイラなど • 例:Xbyak(C++、テンプレート)
DynASM(C、プリプロセッサ) monoasm(Rust、手続きマクロ)
手続きマクロ(proc macro) マクロの中身をRustコードへ変換するRustプログラム monoasm!(jit, pushq rbp;) jit.enc_o(80, Reg::from(5));
fn hello_world() { let func = hello(); func(()); } fn
hello() -> fn(()) -> () { let hello = "hello world!\n"; let mut jit = JitMemory::new(); let label = jit.label(); monoasm!(jit, // prologue pushq rbp; movq rbp, rsp; pushq r15; pushq r14; movq r15, (hello.as_ptr() as u64); movq r14, 13; label: movq rdi, [r15]; movq rax, (test::PUTC as u64); call rax; addq r15, 1; subq r14, 1; cmpq r14, 0; jne label; // epilogue popq r14; popq r15; movq rsp, rbp; popq rbp; ret; ); jit.finalize() }
jit.enc_o(80, Reg::from(5)); jit.enc_rexw_mr(0x89, Reg::from(4), Or::reg(Reg::from(5))); jit.emitb(0xe8); jit.save_reloc(fac, 4); jit.emitl(0); jit.enc_rexw_mr(0x89,
Reg::from(0), Or::reg(Reg::from(15))); jit.enc_rexw_mr(0x89, Reg::from(0), Or::reg(Reg::from(6))); let imm = fmt.as_ptr() as u64; let rm_op = Or::reg(Reg::from(7)); if imm == 0 { jit.enc_rexw_mr(49, Reg::from(7), Or::reg(Reg::from(7))); } else if imm <= 0xffff_ffff { jit.enc_rexw_mi(0xc7, rm_op); jit.emitl(imm as u32); } else { jit.enc_rexw_o(0xb8, Reg::from(7)); jit.emitq(imm); }; monoasm!が吐くRustコード
monoruby • Rubyっぽい文法 • 変数は整数のみ、四則演算できる • if文が使える • 関数・ローカル変数が使える •
パーサはnomを使用 • 抽象構文木をアセンブリに変換
加算命令のコード生成 R12 R13 3 R14 5 R15 stack top R12
R13 8 R14 5 R15 stack top
条件分岐のコード生成
monoruby 1.064 s JS(node) 2.035 s C 0.763 s Ruby
10.700 s Benchmark