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.6k
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
My own Ruby, thereafter
sisshiki1969
0
270
Running Optcarrot (faster) on my own Ruby.
sisshiki1969
1
170
仮想マシンにおけるスタックの管理
sisshiki1969
0
180
Rustでゴミ集め
sisshiki1969
1
300
RustでつくるRubyのFiber
sisshiki1969
0
250
fukuoka.rb#202 RustでつくるRuby
sisshiki1969
1
770
RustでつくるRubyのFiber
sisshiki1969
0
460
Rustでつくるガーベジコレクタ
sisshiki1969
0
640
Other Decks in Programming
See All in Programming
Honoをフロントエンドで使う 3つのやり方
yusukebe
7
3.3k
『GO』アプリ バックエンドサーバのコスト削減
mot_techtalk
0
140
Immutable ActiveRecord
megane42
0
140
動作確認やテストで漏れがちな観点3選
starfish719
6
1k
Rubyで始める関数型ドメインモデリング
shogo_tksk
0
110
Flutter × Firebase Genkit で加速する生成 AI アプリ開発
coborinai
0
160
Open source software: how to live long and go far
gaelvaroquaux
0
630
dbt Pythonモデルで実現するSnowflake活用術
trsnium
0
150
Domain-Driven Transformation
hschwentner
2
1.9k
Unity Android XR入門
sakutama_11
0
160
Rails アプリ地図考 Flush Cut
makicamel
1
120
WebDriver BiDiとは何なのか
yotahada3
1
140
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
336
57k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.1k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Large-scale JavaScript Application Architecture
addyosmani
511
110k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
9
440
Music & Morning Musume
bryan
46
6.3k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
30
4.6k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.3k
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