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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
monochrome
April 27, 2021
Programming
1.7k
0
Share
Shinjuku.rs#15 Rustでつくるx86アセンブラ
Making JIT assembler for x86-64 written in Rust.
monochrome
April 27, 2021
More Decks by monochrome
See All by monochrome
Improving my own Ruby thereafter
sisshiki1969
1
220
あなたとJIT, 今すぐアセンブ ル
sisshiki1969
1
980
Improve my own Ruby
sisshiki1969
1
500
My own Ruby, thereafter
sisshiki1969
0
380
Running Optcarrot (faster) on my own Ruby.
sisshiki1969
1
290
仮想マシンにおけるスタックの管理
sisshiki1969
0
230
Rustでゴミ集め
sisshiki1969
1
360
RustでつくるRubyのFiber
sisshiki1969
0
310
fukuoka.rb#202 RustでつくるRuby
sisshiki1969
1
860
Other Decks in Programming
See All in Programming
へんな働き方
yusukebe
6
2.9k
VueエンジニアがReactを触って感じた_設計の違い
koukimiura
0
150
The free-lunch guide to idea circularity
hollycummins
0
410
Migration to Signals, Signal Forms, Resource API, and NgRx Signal Store @Angular Days 03/2026 Munich
manfredsteyer
PRO
0
230
Feature Toggle は捨てやすく使おう
gennei
0
410
Linux Kernelの1文字のミスで 権限昇格ができた話
rqda
0
2.3k
「効かない!」依存性注入(DI)を活用したAPI Platformのエラーハンドリング奮闘記
mkmk884
0
300
ファインチューニングせずメインコンペを解く方法
pokutuna
0
260
RSAが破られる前に知っておきたい 耐量子計算機暗号(PQC)入門 / Intro to PQC: Preparing for the Post-RSA Era
mackey0225
3
120
メッセージングを利用して時間的結合を分離しよう #phperkaigi
kajitack
3
550
年間50登壇、単著出版、雑誌寄稿、Podcast出演、YouTube、CM、カンファレンス主催……全部やってみたので面白さ等を比較してみよう / I’ve tried them all, so let’s compare how interesting they are.
nrslib
4
690
レガシーPHP転生 〜父がドメインエキスパートだったのでDDD+Claude Codeでチート開発します〜
panda_program
0
200
Featured
See All Featured
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.4k
Skip the Path - Find Your Career Trail
mkilby
1
94
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
170
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.1k
Prompt Engineering for Job Search
mfonobong
0
250
Technical Leadership for Architectural Decision Making
baasie
3
310
How to Talk to Developers About Accessibility
jct
2
170
Google's AI Overviews - The New Search
badams
0
960
How to Think Like a Performance Engineer
csswizardry
28
2.5k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.2k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
170
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