鍍金池/ 教程/ Java/ 內(nèi)聯(lián)匯編
While 循環(huán)
宏命令
模式
Rust 嵌入到其他語言
變量綁定
if
發(fā)布通道
Lang 項(xiàng)目
匹配
文檔
棧和堆
不依賴 stdlib
原始指針
條件編譯
type 別名
關(guān)聯(lián)類型
全類型
詞匯表
基本類型
Hello, world!
測試
箱和模塊
字符串
向量
引用與借用
所有權(quán)
內(nèi)斂函數(shù)
基準(zhǔn)測試
Nightly Rust
for 循環(huán)
特征
特征的對象
鏈接參數(shù)
介紹
'Deref'強(qiáng)制轉(zhuǎn)換
枚舉
內(nèi)聯(lián)匯編
泛型
方法語法
函數(shù)
外部函數(shù)接口
盒語法和模式
安裝 Rust
unsafe    
生存期
切片模式
Borrow 和 AsRef
If let
學(xué)習(xí) Rust
“常量”和“靜態(tài)”
語法和語義
迭代器
相關(guān)學(xué)術(shù)研究
通用函數(shù)調(diào)用語法
哲學(xué)家就餐問題
類型轉(zhuǎn)換
閉包
并發(fā)性
Hello, Cargo!
屬性
注釋
結(jié)構(gòu)體
編譯器插件
高效 Rust
相關(guān)常量
猜謎游戲
可變性
錯誤處理
新手入門
操作符和重載

內(nèi)聯(lián)匯編

由于低水平的操作和性能,人們希望直接控制 CPU。Rust 通過 asm!宏來支持使用內(nèi)聯(lián)匯編。語法大致匹配 GCC & Clang :

asm!(assembly template
   : output operands
   : input operands
   : clobbers
   : options
   );

任何 asm 的使用是特征封閉的(需要庫的 #![feature(asm)] 允許),當(dāng)然需要一個 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 和選擇項(xiàng)都是可選的,但是你必須添加正確的數(shù)量的 : 如果你跳過它們:

asm!("xor %eax, %eax"
:
:
: "{eax}"
   );

空格也沒有關(guān)系:

asm!("xor %eax, %eax" ::: "{eax}");

操作數(shù)

輸入和輸出操作數(shù)遵循相同的格式:"constraints1"(expr1), "constraints2"(expr2), ..."。輸出操作數(shù)表達(dá)式必須是可變左值,或者沒有分配內(nèi)存:

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

Clobbers    

一些指令修改有可能持有不同值的寄存器,所以我們使用超時列表來指示編譯器不承擔(dān)加載到寄存器將保持有效的任何值。

// Put the value 0x200 in eax
asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "{eax}");

輸入和輸出寄存器不需要被列出來,因?yàn)樾畔⒁呀?jīng)被給定約束傳達(dá)。否則,任何其他被隱式或顯式地使用的寄存器應(yīng)該列出?!   ?/p>

如果內(nèi)聯(lián)會更改代碼寄存器, cc 應(yīng)該指定為一個 clobber。同樣,如果內(nèi)聯(lián)會修改內(nèi)存,memory 還應(yīng)該被指定。

選擇項(xiàng)

最后一部分,options 是 Rust 特有的。形式是逗號分隔字符串(例如::"foo", "bar", "baz")。這是用于指定內(nèi)聯(lián)匯編的一些額外的信息:    

當(dāng)前有效的選項(xiàng)是:    

  1. volatile -這類似于在 gcc/clang 中指定_ _asm__ __volatile__(...) 。  
  2. alignstack-某些指定堆的對齊某種方式(例如,SSE)的指令并說明這個指示編譯器插入其通常堆棧對齊的代碼的指令。 
  3. intel -使用 intel 語法而不是默認(rèn)的 AT&T。

      let result: i32;
      unsafe {
         asm!("mov eax, 2" : "=`{eax}"(result) : : : "intel")
      }  println!("eax is currently {}", result);
上一篇:相關(guān)常量下一篇:全類型