Rust Inline ASM

rust和c/c++一样,可以内联汇编.语法和c/c++的内联汇编大致一样.只有几个细节稍有不同.

首先,需要开启一个特性 #![feature(asm)]

然后在asm!宏里面写汇编即可.

格式是:

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

大致和c/c++相同.其中有几个不同点:

在最后一段用来声明已经使用过的寄存器的那一段(clobbers)下面还可以跟一段option段.备选项有:“intel”表示采用intel汇编而不像c那样用AT&T汇编.“volatile”,和c里面的__asm__volatile__一样.“alignstack”,让编译器自动插入对齐栈的代码(因为有些指令集需要对齐栈,比如SSE指令集). 在填充模版的时候,变量用$0,$1来表示,而不是c的%1,%2来表示. 立即数用$$表示,$$1就是1. 寄存器直接用%来表示,%eax表示eax寄存器 模版里面多条指令用分号(;)来分割,而不是c的”\r\n” 声明clobber的时候直接写eax,不用像C那样写%eax 记得asm!的时候要外面套unsafe块 intel语法我没有试过.所以无从比较语法区别:(

下面附上我的一个小例子,用汇编+偏移量来访问数组.

#![feature(asm)]
	
fn main() {asm();}

#[cfg(target_arch = "x86_64")]
fn asm() {
	use std::mem::transmute;
	use std::rand::random;
			
	let array: &[u64] = &[random(),random(),random(),random()];
	
	let address = unsafe { transmute::<_, (i64, i64)>(array).0 };
	
	for offset in 0u64..4 {
	 	let ret: u64;
	 	unsafe {
	 		asm!(
	 			r"
	 			mov ($1, $2, 8), %rax;
	 			mov %rax, $0;
	 			"
	 			: "=r"(ret)
	 			: "r"(address), "r"(offset)
	 			: "rax"
	 			:
	 			);
	 	}
	 	println!("在第{}号位上的元素是{}", offset, ret);
	 }
}
comments powered by Disqus