CodeBlanks Logo Icon CodeBlanks

Options

pure, nomem, nostack options'larını kullanırsın.

Options

Varsayılan olarak derleyici, assembly bloğunun belleği okuyup yazabileceğini, yığını kullanabileceğini ve yan etkileri olduğunu varsayar; bu, optimizasyonu kısıtlar. options(..) ile daha güçlü vaatler verilir:

let y: u64;
unsafe {
    asm!(
        "lea {o}, [{a} + {a}*2]",     // o = a * 3
        a = in(reg) x,
        o = lateout(reg) y,
        options(pure, nomem, nostack),
    );
}
  • pure: yan etkisi yok, çıktı yalnızca girdilere bağlı; sonuç kullanılmazsa blok silinebilir.
  • nomem: belleğe dokunmaz.
  • nostack: yığına yazmaz.

lea ile hızlı aritmetik

lea (load effective address) aslında bellek okumaz; adres hesaplama donanımını kullanarak a + b*k (k = 1, 2, 4, 8) biçiminde toplama ve çarpmayı tek talimatta yapar. Derleyiciler x * 3, x * 5 gibi çarpımları sıklıkla böyle üretir. Bu da çoğu zaman elle assembly'ye gerek olmadığını gösterir: x * 3 yazmak aynı talimatı üretir.

// derleyicinin x * 3 için ürettiği tipik kod:
// lea rax, [rdi + rdi*2]

Uygulama Üç katı

x86-64 için lea ve options(pure, nomem, nostack) kullanan fn uc_kat(x: u64) -> u64 yaz (diğer mimarilerde x * 3). uc_kat(5) sonucunu yazdır.

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
#[cfg(target_arch = "x86_64")]
fn uc_kat(x: u64) -> u64 {
    let y: u64;
    // SAFETY: lea belleğe erişmez; seçenekler doğrudur.
    unsafe {
        std::arch::asm!(
            "lea {o}, [{a} + {a}*2]",
            a = in(reg) x,
            o = lateout(reg) y,
            options(pure, nomem, nostack),
        );
    }
    y
}

#[cfg(not(target_arch = "x86_64"))]
fn uc_kat(x: u64) -> u64 {
    x * 3
}

fn main() {
    println!("{}", uc_kat(5));
}

Beklenen çıktı

15

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Belleğe yazan bir bloğa <code>nomem</code> denirse ne olur?

  • Derleme hatası
  • Yavaşlar
  • Bir şey olmaz
  • Tanımsız davranış: derleyici bellek değerlerinin değişmediğini varsayar Doğru cevap

Açıklama: Seçenekler derleyiciye verilen sözlerdir ve denetlenmez; yanlış söz, yanlış optimizasyon demektir.

2 Saf blok

Soru
asm!(
    "lea {o}, [{a} + {a}*2]",
    a = in(reg) x,
    o = lateout(reg) y,
    options(____, nomem, nostack),
);
Cevap
asm!(
    "lea {o}, [{a} + {a}*2]",
    a = in(reg) x,
    o = lateout(reg) y,
    options(pure, nomem, nostack),
);

Açıklama: pure, bloğun yan etkisiz olduğunu ve yalnızca girdilere bağlı sonuç ürettiğini bildirir.

3 Seçenek ve vaadi

Kavram Anlamı
pure Yan etki yok
nomem Belleğe dokunmaz
nostack Yığına yazmaz
readonly Belleği yalnızca okur

Uzman bölümündeki tüm dersler