CodeBlanks Logo Icon CodeBlanks

Register

Özel register belirtmeyi öğrenirsin.

Register

Bazı talimatlar belirli yazmaçları kullanır (örneğin x86'da mul, div, cpuid, sistem çağrıları). Böyle durumlarda yazmaç sınıfı yerine yazmacın adı tırnak içinde verilir:

let mut x: u64 = 6;
let y: u64 = 7;
unsafe {
    asm!(
        "imul rax, rcx",
        inout("rax") x,
        in("rcx") y,
    );
}
// x == 42

Açık yazmaçlar şablonda {} ile değil, doğrudan adıyla yazılır. Bazı yazmaçlar (yığın işaretçisi rsp, çerçeve işaretçisi rbp gibi) operand olarak kullanılamaz.

Bozulan yazmaçlar

mul sonucu rdx:rax çiftine yazar; rdx kullanılmasa bile bozulduğu bildirilmelidir:

let mut a: u64 = 6;
unsafe {
    asm!(
        "mul {b}",
        b = in(reg) 7u64,
        inout("rax") a,
        out("rdx") _,        // rdx bozuldu, değeri gerekmiyor
    );
}

Fonksiyon çağıran assembly için clobber_abi("C") seçeneği, çağrı kuralının bozabileceği tüm yazmaçları tek seferde bildirir.

Uygulama Açık yazmaçlarla çarpım

x86-64 için imul rax, rcx talimatını açık yazmaçlarla kullanan fn carp(x: u64, y: u64) -> u64 yaz (diğer mimarilerde x * y). carp(6, 7) sonucunu yazdır.

Başlangıç kodu

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

Örnek çözüm

main.rs
#[cfg(target_arch = "x86_64")]
fn carp(mut x: u64, y: u64) -> u64 {
    // SAFETY: yalnızca rax ve rcx kullanılır ve ikisi de bildirilmiştir.
    unsafe {
        std::arch::asm!(
            "imul rax, rcx",
            inout("rax") x,
            in("rcx") y,
        );
    }
    x
}

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

fn main() {
    println!("{}", carp(6, 7));
}

Beklenen çıktı

42

Soru ve cevaplar

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

1 Bir talimat bir yazmacı bozuyor ama sen onun değerini kullanmıyorsan ne yapmalısın?

  • out("reg_adı") _ ile derleyiciye bildirmek Doğru cevap
  • Hiçbir şey
  • unsafe'i kaldırmak
  • Yazmacı kaydedip geri yüklemek her zaman

Açıklama: Bildirilmeyen bir yazmacı değiştirmek, derleyicinin orada tuttuğu değeri sessizce bozar: tanımsız davranış.

2 Belirli yazmaç

Soru
asm!(
    "imul rax, rcx",
    inout(____) x,
    in("rcx") y,
);
Cevap
asm!(
    "imul rax, rcx",
    inout("rax") x,
    in("rcx") y,
);

Açıklama: Belirli bir yazmaç, adı tırnak içinde verilerek seçilir.

3 Yazım ve anlamı

Kavram Anlamı
in(reg) x Derleyici yazmaç seçer
in("rcx") y rcx zorunlu
out("rdx") _ Bozulan yazmaç
clobber_abi("C") Çağrı kuralı yazmaçları

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