W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
由于低水平的操作和性能,人們希望直接控制 CPU。Rust 通過 asm!宏來支持使用內聯(lián)匯編。語法大致匹配 GCC & Clang :
asm!(assembly template
: output operands
: input operands
: clobbers
: options
);
任何 asm 的使用是特征封閉的(需要庫的 #![feature(asm)] 允許),當然需要一個 unsafe 塊。
注意:這里給出了 x86 和 x86-64 支持的例子,但所有平臺都支持
assembly template 是唯一所需的參數(shù),它必須是一個文字字符串(例如,"")
#![feature(asm)]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn foo() {
unsafe {
asm!("NOP");
}
}
// other platforms
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
fn foo() { /* ... */ }
fn main() {
// ...
foo();
// ...
}
(從現(xiàn)在開始省略 feature(asm) 和 #[cfg]。)
輸出操作數(shù),輸入操作數(shù),clobber 和選擇項都是可選的,但是你必須添加正確的數(shù)量的 : 如果你跳過它們:
asm!("xor %eax, %eax"
:
:
: "{eax}"
);
空格也沒有關系:
asm!("xor %eax, %eax" ::: "{eax}");
輸入和輸出操作數(shù)遵循相同的格式:"constraints1"(expr1), "constraints2"(expr2), ..."。輸出操作數(shù)表達式必須是可變左值,或者沒有分配內存:
fn add(a: i32, b: i32) -> i32 {
let c: i32;
unsafe {
asm!("add $2, $0"
: "=r"(c)
: "0"(a), "r"(b)
);
}
c
}
fn main() {
assert_eq!(add(3, 14159), 14162)
}
如果你想在這個位置上使用真正的操作數(shù),然而,你需要把花括號 { } 放在你想要的的寄存器兩邊,你需要加具體操作數(shù)的大小。對于低水平的編程這是非常有用的,在程序中使用哪個寄存器很重要:
let result: u8;
asm!("in %dx, %al" : "={al}"(result) : "{dx}"(port));
result
一些指令修改有可能持有不同值的寄存器,所以我們使用超時列表來指示編譯器不承擔加載到寄存器將保持有效的任何值。
// Put the value 0x200 in eax
asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "{eax}");
輸入和輸出寄存器不需要被列出來,因為信息已經(jīng)被給定約束傳達。否則,任何其他被隱式或顯式地使用的寄存器應該列出?! ?/p>
如果內聯(lián)會更改代碼寄存器, cc 應該指定為一個 clobber。同樣,如果內聯(lián)會修改內存,memory 還應該被指定。
最后一部分,options 是 Rust 特有的。形式是逗號分隔字符串(例如::"foo", "bar", "baz")。這是用于指定內聯(lián)匯編的一些額外的信息:
當前有效的選項是:
intel -使用 intel 語法而不是默認的 AT&T。
let result: i32;
unsafe {
asm!("mov eax, 2" : "=`{eax}"(result) : : : "intel")
} println!("eax is currently {}", result);
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: