Rust 内测全新的汇编内嵌语法,Ngihtly版可尝试

yumo6661个月前 (05-11)技术文章8

在系统优化、OS或嵌入式开发及其他类型的低级编程过程中,有时可能需要变现原生的汇编程序。"内嵌汇编"提供了一种将某些汇编指令集成到Rust语法中然后输入寄存器以及将其输出直接引入到Rust 变量的简单方法。

Rust 的Ngihtly版中对"内嵌汇编"新引入了一种新的语法在在内侧。

Ngihtly Rust 支持"内嵌汇编"的(asm!) 的语法已有很长一段时间了。但是,该语法只是公开了一部分纯原始的LLVM 程序集,而且不支持开发人员安全使用的帮助措施。在这种枪口下,如果稍有错误,就会产生内部编译器错误(ICE),而不是友好的rustc异常警告。另外,这些原生的语法也不易读,容易出错(看上去就像是GCC的内联程序集语法,但存在细微差异(如寄存器约束中的名称)。该语法也基本上不支持任何非LLVM后端。由于这种种限制,虽然asm!是用户呼声最高的功能之一,但是不太适合迁移到稳定的Rust版本中。


为了改进asm!让更多用户可以使用,Amanieu d'Antras新设计和实现了一种全新的、更友好的语法。从概念到编译器实现,新语法还有很长的路要走:


该提案最初是作为内部RFC的前一项。

为内嵌汇编成为语言团队的第一项目组之一,并在项目组仓库中反复设计和讨论。

RFC 2873(仍在讨论中)为asm!语法及其和Rust语言的交互提供了规范。

已将老的asm!重命名为llvm_asm!(鉴于此语法脆弱的 ICE 快乐特性,最终计划会删除此语法,但在评估新语法时,希望旧语法可用于比较和替代方法。)

PR 69171(也是由 Amanieu)在夜间实现了新asm!的语法。

下面是使用新的内嵌汇编语法,使用 x86-64 Linux 上的直接写入系统调用将消息打印到标准输出的示例:


#![feature(asm)]
fn main() {
let buf = "Hello from asm!\n";
let ret: i32;
unsafe {
asm!(
"syscall",
in("rax") 1, // syscall number
in("rdi") 1, // fd (stdout)
in("rsi") buf.as_ptr(),
in("rdx") buf.len(),
out("rcx") _, // clobbered by syscalls
out("r11") _, // clobbered by syscalls
lateout("rax") ret,
);
}
println!("write returned: {}", ret);
}


注:该实例可以直接在线上playground运行和测试。

上面的示例指定了Linux系统通过寄存器调用特定的确切的输入、输出。我们还可以通过任意寄存器提供输入和输出,编译器将为我们选择适当的寄存器。下面的示例使用位操作指令计算值中所有设置位的位数,并将它们存储在内存切片中:


#![feature(asm)]

fn main() {
let mut bits = [0u8; 64];
for value in 0..=1024u64 {
let popcnt;
unsafe {
asm!("
popcnt {popcnt}, {v}
2:
blsi rax, {v}
jz 1f
xor {v}, rax
tzcnt rax, rax
stosb
jmp 2b
1:
",
v = inout(reg) value => _,
popcnt = out(reg) popcnt,
out("rax") _, // scratch
inout("rdi") bits.as_mut_ptr() => _,
);
}
println!("bits of {}: {:?}", value, &bits[0..popcnt]);
}
}

注:该实例可以直接在线上playground运行和测试。该代码主要用于演示内联程序集,而不是演示任何特定算法实现的有效性。可注意到已为value和popcnt选择了寄存器,同时bits.as_mut_ptr()必须转到rdi寄存器中,以便使用stosb指令。

此外在 x86 平台上,默认情况下使用英特尔语法;但是,asm!可以通过option(att_syntax)使用AT&T语法。将已有的内嵌汇编代码转换为asm!新语法时,可使用这个语法。

有关新语法的完整详细信息,请参阅Rust官方RFC 2873。如果已经使用asm!编写代码的建议请将现有内嵌汇编程序转换为新语法,如果发现问题和bug请及时上报。

相关文章

汇编入门第一篇,小白也能看懂(汇编 入门)

cxuan自己的 Github 非常硬核,求各位大佬 star: https://github.com/crisxuan/bestJavaer汇编代码是计算机的一种低级表示,它是一种低级语言,可以从字...

01程序编译过程分析,预处理,编译,汇编,链接

前言 我们大多数开发人员在编写完程序之后都会通过相应的IDE执行编译的操作,将所编写的源代码转换成计算机可以识别并执行的文件。这个从源代码转换成可执行文件的过程有相应的IDE帮助我们完成,很多朋友对于...

单片机入门-要从汇编开始(单片机汇编基础知识)

简介单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器、显示驱动电路、脉宽调制电路、模...

万字详文:Golang 汇编入门知识总结,看这一篇就够了

作者:ivansli,腾讯 IEG 运营开发工程师在深入学习 Golang 的 runtime 和标准库实现的时候发现,如果对 Golang 汇编没有一定了解的话,很难深入了解其底层实现机制。在这里整...

新手攻略!入门ARM必须要理解的22个常用概念

罗列了关于ARM的22个常用概念。包括一些使用注意事项、ARM启动代码设计、ARM处理器运行模式、ARM体系结构所支持的异常类型和一些基本操作方法等等。01ARM中一些常见英文缩写解释MSB:最高有效...

芯片的这些常见分类了解一下(一)(芯片种类分类)

芯片的使用地方非常的多,所以在芯片的分裂上种类也有很多,这些应该也是大家都知道的,但是芯片有哪些分类你搞得清楚吗?1、内存储器按存储信息的功能可分为随机存储器RAM(RandomAccess Memo...