Rust
Operand
in, out, inout operandlarını kullanırsın.
Operand
Operandlar Rust değişkenlerini assembly'ye bağlar:
in(reg) x: yalnızca girdi.out(reg) y: yalnızca çıktı; başlangıç değeri anlamsız.inout(reg) z: hem girdi hem çıktı.lateout(reg) y: tüm girdiler okunduktan sonra yazılan çıktı; derleyici bir girdinin yazmacını yeniden kullanabilir.
let t: u64;
unsafe {
asm!(
"mov {o}, {a}",
"add {o}, {b}",
a = in(reg) 5u64,
b = in(reg) 6u64,
o = out(reg) t,
);
}
// t == 11
Adlandırılmış operandlar ({a}) birden çok satırlı kodu okunur kılar.
Yazmaç sınıfları
reg genel amaçlı yazmaç sınıfıdır. Diğer sınıflar: x86'da xmm_reg, ymm_reg (vektör), reg_byte (8 bit). Değerin boyutu yazmacın hangi parçasının kullanılacağını belirler; açıkça seçmek için şablon değiştiricileri vardır: {0:e} 32 bitlik eax gibi adı, {0:r} 64 bitlik rax gibi adı verir.
let mut x: u32 = 0x11223344;
unsafe { asm!("bswap {0:e}", inout(reg) x) }; // 32 bit bayt ters çevirme
Uygulama Adlandırılmış operandlar
Yukarıdaki iki talimatlı örneği x86-64 için fn topla(a: u64, b: u64) -> u64 olarak yaz (diğer mimarilerde a + b). topla(5, 6) sonucunu yazdır.
Örnek çözümü göster
#[cfg(target_arch = "x86_64")]
fn topla(a: u64, b: u64) -> u64 {
let t: u64;
// SAFETY: yalnızca operand yazmaçlarını kullanır.
unsafe {
std::arch::asm!(
"mov {o}, {a}",
"add {o}, {b}",
a = in(reg) a,
b = in(reg) b,
o = out(reg) t,
);
}
t
}
#[cfg(not(target_arch = "x86_64"))]
fn topla(a: u64, b: u64) -> u64 {
a + b
}
fn main() {
println!("{}", topla(5, 6));
}
Kendini test et
-
Yukarıdaki örnekte <code>o</code> için <code>lateout</code> kullanmak neden hatalı olabilir?
- Hatalı değildir
- o ilk talimatta yazılıyor ama b henüz okunmadı; derleyici o ile b'ye aynı yazmacı verebilir
- lateout yoktur
- Daha yavaştır
Cevabı göster
o ilk talimatta yazılıyor ama b henüz okunmadı; derleyici o ile b'ye aynı yazmacı verebilir — lateout yalnızca tüm girdiler kullanıldıktan sonra yazılan çıktılar için güvenlidir.
-
Yalnızca çıktı
asm!(
"mov {o}, {a}",
a = in(reg) 5u64,
o = ____(reg) t,
);
Cevabı göster
asm!(
"mov {o}, {a}",
a = in(reg) 5u64,
o = out(reg) t,
);
-
Operand ve yönü
- in(reg) x
- Rust → asm
- out(reg) y
- asm → Rust
- inout(reg) z
- İki yön
- lateout(reg) y
- Girdilerden sonra çıktı
Sıradaki ders: Register