第82回です。前回はこちら。
[第82回の様子]
2023/06/21に第82回を開催した。
内容としてはRust By Example 日本語版22. 安全でない操作の「22.1. Inline assembly」のClobbered registersに取り組んだ...が終わらず。来週も続きをやるぞ〜。
参加者は自分を入れて6人。今回は最近加入した新人さんがドライバやってくれた!
[学んだこと]
- 22.1. Inline assembly: Clobbered registers
- Clobberedは「破壊された」とかいう意味らしい
- インラインアセンブリは出力の必要がないレジスタの状態を変更する
- このレジスタの状態を「Clobberd」という
- 従って、インラインアセンブリの前後で、レジスタの状態を保存・復旧させるためにRustのコンパイラに伝える必要がある
- ただ、サンプルコードのコメントを読んだところで時間ぎれになってしまい、どのようにコンパイラに伝えているのかはわからないまま終わってしまった...
use std::arch::asm;
fn main() {
// 4バイト×3つ分
let mut name_buf = [0_u8; 12];
// 文字列はASCIIコードとしてebx, edx, ecxに保管される
// ebxは予約されているので、その値を保存するためにpush/popが必要
unsafe {
asm!(
"push rbx",
"cpuid",
"mov [rdi], ebx",
"mov [rdi + 4], edx",
"mov [rdi + 8], ecx",
"pop rbx",
// Rustコードをシンプルにするために、アセンブリのコードを増やして
// 配列へのポインタを用いて値を保存する
// `out("ecx") val`のように明示的な出力レジスタを利用するのと対照的に、
// アセンブリの動きはより明示的になる
// ポインタそのものはあくまで入力として扱われる
in("rdi") name_buf.as_mut_ptr(),
// cpuid 0を選択し、eaxをclobberedに指定する
inout("eax") 0 => _,
// cpuidは以下のレジスタもclobberする
out("ecx") _,
out("edx") _,
);
}
// バイト列を文字列に変換
let name = core::str::from_utf8(&name_buf).unwrap();
println!("CPU Manufacturer ID: {}", name);
// CPU Manufacturer ID: AuthenticAMD
}
- わからないところが残ってしまったので、次回はコードの後につづく解説を読んでいく
[まとめ]
モブプログラミングスタイルでRust dojoを開催した。
レジスタむずいっていうか、内容がどんどん難しくなってきて、英単語がわかっても意味がわからない、そもそも英単語がわからない文章が増えてきた。つらい...。
今週のプルリクエストはおやすみ。