kdnakt blog

hello there.

Rust dojo第88回を開催した

第88回です。前回はこちら。

kdnakt.hatenablog.com

[第88回の様子]

2023/08/09に第88回を開催した。

内容としてはRust By Example 日本語版22. 安全でない操作の「22.1. Inline assembly」のLabelsのつづきと、Optionsの途中まで取り組んだ。ようやくインラインアセンブリの章の終わりが見えてきた...。
参加者は自分を入れて7人。

[学んだこと]

use std::arch::asm;

fn main() {
    let mut a = 0;
    unsafe {
        asm!(
            "mov {0}, 10",
            "2:",
            "sub {0}, 1",
            "cmp {0}, 3",
            "jle 2f",
            "jmp 2b",
            "2:",
            "add {0}, 2",
            out(reg) a
        );
    }
    assert_eq!(a, 5);
}
  • アセンブリに詳しい人の解説を聞きながらコードを読んでいく
  • movは代入、subは引き算、cmpは比較、jleは比較結果がless than or equals toだったらジャンプ、jmpはジャンプ
  • ジャンプ先のラベルで2f、2bが指定されている
    • 2のラベルが重複しているので、前後どちらに飛ぶかforward、backwardで指定するらしい
  • 全体としては、10を代入して3になるまで1引いて、最後に2を足すアセンブリになっている
  • 多分JavaScriptで書くとこんな感じ?whileの方が良かったかも。
var a = 10;
for (; a <= 3; a--) { }
a += 2;
console.log(a)
  • COBOL時代はこのアセンブリみたいなgoto命令を使う感じのコードがよくあった、らしい。たまにCOBOL時代を知る先輩がいて強い。
  • ちなみに、アセンブリを以下のようにして重複ラベルを3つにしてもちゃんとコードが動いた
asm!(
    "mov {0}, 10", // a=10
    "2:",
    "sub {0}, 1", // a-=1
    "cmp {0}, 3", // if a<=3
    "jle 2f",
    "jmp 2b",
    "2:",
    "add {0}, 5", //a+=5;
    "jmp 2f",
    "add {0}, 7", //デッドコード 
    "2:",
    "add {0}, 2",
    out(reg) a
);
// aは10になっている
use std::arch::asm;

let mut a: u64 = 4;
let b: u64 = 4;
unsafe {
    asm!(
        "add {0}, {1}",
        inlateout(reg) a, in(reg) b,
        options(pure, nomem, nostack),
    );
}
assert_eq!(a, 8);
  • コードの内容としては4に4を足すだけ
  • optionの詳細な内容は時間が足りなかったので次回。

[まとめ]

モブプログラミングスタイルでRust dojoを開催した。

やっとインラインアセンブリの章が終わりそうで一安心。

今週のプルリクエストはおやすみ。