Register
- Rust kursu
- Uzman
- Ders 27/46
- 4 dk
Ö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 == 42Açı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
fn main() {
// buraya yaz
}Örnek çözüm
#[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ç
asm!(
"imul rax, rcx",
inout(____) x,
in("rcx") y,
);
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ı |