$30 off During Our Annual Pro Sale. View Details »
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.7k
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
Improving my own Ruby thereafter
sisshiki1969
1
190
あなたとJIT, 今すぐアセンブ ル
sisshiki1969
1
870
Improve my own Ruby
sisshiki1969
1
400
My own Ruby, thereafter
sisshiki1969
0
340
Running Optcarrot (faster) on my own Ruby.
sisshiki1969
1
250
仮想マシンにおけるスタックの管理
sisshiki1969
0
210
Rustでゴミ集め
sisshiki1969
1
340
RustでつくるRubyのFiber
sisshiki1969
0
300
fukuoka.rb#202 RustでつくるRuby
sisshiki1969
1
830
Other Decks in Programming
See All in Programming
DSPy Meetup Tokyo #1 - はじめてのDSPy
masahiro_nishimi
1
110
dnx で実行できるコマンド、作ってみました
tomohisa
0
110
競馬で学ぶ機械学習の基本と実践 / Machine Learning with Horse Racing
shoheimitani
14
14k
手軽に積ん読を増やすには?/読みたい本と付き合うには?
o0h
PRO
1
120
251126 TestState APIってなんだっけ?Step Functionsテストどう変わる?
east_takumi
0
270
TypeScript 5.9 で使えるようになった import defer でパフォーマンス最適化を実現する
bicstone
1
540
AIコードレビューがチームの"文脈"を 読めるようになるまで
marutaku
0
170
目的で駆動する、AI時代のアーキテクチャ設計 / purpose-driven-architecture
minodriven
11
3.6k
Evolving NEWT’s TypeScript Backend for the AI-Driven Era
xpromx
0
210
しっかり学ぶ java.lang.*
nagise
1
460
WebRTC と Rust と8K 60fps
tnoho
2
830
Building AI Agents with TypeScript #TSKaigiHokuriku
izumin5210
5
1.1k
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
527
40k
Six Lessons from altMBA
skipperchong
29
4.1k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
680
Testing 201, or: Great Expectations
jmmastey
46
7.8k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
36
6.1k
Documentation Writing (for coders)
carmenintech
76
5.1k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.8k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.4k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.1k
GraphQLとの向き合い方2022年版
quramy
49
14k
A Tale of Four Properties
chriscoyier
162
23k
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