kdnakt blog

hello there.

Rust dojo第87回を開催した

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

kdnakt.hatenablog.com

[第87回の様子]

2023/08/02に第87回を開催した。

内容としてはRust By Example 日本語版22. 安全でない操作の「22.1. Inline assembly」のMemory address operandsとLabelsの途中まで取り組んだ。
参加者は自分を入れて6人。

そろそろ教材が終わりそうなので、次はHaskell dojoをやろうか、などと話している今日この頃。

[学んだこと]

use std::arch::asm;

fn load_fpu_control_word(control: u16) {
    unsafe {
        asm!("fldcw [{}]", in(reg) &control, options(nostack));
    }
}
  • fldcwは浮動小数点の丸めの設定をする命令らしい

www.oishi.info.waseda.ac.jp

  • それらしいコードを何度か試してみたが、うまく出力を変えることができなかった...
use std::arch::asm;

fn load_fpu_control_word(control: u16) {
    unsafe {
        asm!("fldcw [{}]", in(reg) &control, options(nostack));
    }
}

fn calc() -> f64 {
    1.0 / 0.3
}

fn main() {
    let a = calc();
    println!("a: {a}"); // a: 3.3333333333333335

    // let round_up = 0x1b3a;
    let round_down = 0x173a;
    load_fpu_control_word(round_down);
    
    let b = calc();
    println!("b: {b}"); // b: 3.3333333333333335
}
  • これだと[]でメモリアドレスを見れているかわからなかったのでmov命令で書き直してみた
use std::arch::asm;

fn f(input: &i32) -> i32 {
    let ret: i32;
    unsafe {
        asm!("mov {}, [{}]",
            out(reg) ret,
            in(reg) input,
        );
    }
    ret
}

fn main() {
    let a = 100;
    let b = f(&a);
    println!("b: {b}"); // b: 100
}
  • 22.1. Inline assembly: Labels
  • アセンブリのラベルの話。
  • ラベルを再利用すると、アセンブラまたはリンカーのエラーが発生したり、奇妙な挙動が発生してしまう可能性がある
  • 再利用にはいくつかのパターンがある
    • 明示的にasm!ブロック内やasm!ブロック間で複数回利用する場合
    • asm!のインライン化で暗黙的に複数回利用される場合
    • LTO(Link Time Optimization?)他のクレートのコードによって暗黙的に利用される場合
  • ラベルでシンボルを定義するとエラーになる可能性があるので、数値のローカルラベルのみ利用可能
  • さらに、Intelx86の場合、LLVMのバグで0や1だけからなるラベル(0、11、101010)はバイナリ値として扱われるため利用できない
    • options(att_syntax)を使うとこの問題を回避できるが、asm!ブロックの書き方に影響するので要注意
  • サンプルコードが書かれていたが今回は時間切れ。次回に持ち越し...

[まとめ]

モブプログラミングスタイルでRust dojoを開催した。
プロセッサによって色々違うんだなあ...。

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