当前位置: 首页 > news >正文

2510rs,稳定裸函数

原文

稳定裸函数

Rust1.88.0稳定了用来定义裸函数#[unsafe(naked)]属性和naked_asm!宏.

裸函数是标有#[unsafe(naked)]属性,主体由单个naked_asm!调用组成的.如:

    //安全:遵守`64`位`SystemVABI`.
#[unsafe(naked)]
pub extern "sysv64" fn wrapping_add(a: u64, b: u64) -> u64 {//相当于`"a.wrapping_add(b)"`.core::arch::naked_asm!("lea rax, [rdi + rsi]","ret");
}

裸函数的特别之处,是因为手写汇编块定义了整个函数体.与非裸函数不同,编译器不会特殊处理参数或返回值.

此功能是替代使用global_asm!定义函数的,他更符合人体工程学.裸函数用在低级设置,如Rust编译器内置,操作系统和嵌入式应用.

为什么要使用裸函数

但是等等,如果裸函数只是global_asm!的语法糖,为什么要首先添加它们?

为了了解好处,来使用global_asm!重写介绍中的wrapping_add示例:

//安全:`此模块`中定义了`"wrapping_add"`,并期望`64`位`SystemVABI`.
unsafe extern "sysv64" {safe fn wrapping_add(a: u64, b: u64) -> u64
}
core::arch::global_asm!(r#"//构成相关平台的指令的函数..section .text.wrapping_add,"ax",@progbits.p2align 2.globl wrapping_add.type wrapping_add,@function
wrapping_add:lea rax, [rdi + rsi]ret
.Ltmp0:.size wrapping_add, .Ltmp0wrapping_add"#
);

汇编块以定义函数期望指令(.section,.p2align等)开始和结束.这些指令是机械的,但它们在目标文件格式之间有所不同.
裸函数将自动发出正确的指令.

接着,wrapping_add名是硬编码的,不会参与Rust名混杂.这使得编写跨平台代码更难,因为不同目标不同名混杂方案(如x86_64,macOS在符号前缀为_,但林操没有).

解混杂的符号也是全局可见的,这样块可找到它,从而导致解析符号冲突.裸函数名确实参与了名混杂,且不会遇见这些问题.

此例未显示的另一个限制是,使用全局汇编定义的函数不能使用模板.特别是模板与汇编结合使用很有用.

最后,只有一个定义可为(安全)文档和属性提供一致的位置,降低它们过时的风险.适当的安全注释对裸函数至关重要.
因为ABI(这里为sysv64),裸属性是不安全的,签名和实现必须一致.

extern"``自定义"函数

裸函数一般带extern"C"``调用约定.但一般,该调用约定是谎言.许多时候,裸函数不会实现Rust知道的ABI.相反,它们使用相关该函数的一些自定义调用约定.

abi_custom功能添加了extern"``自定义"函数和块,这使可从编译器内置中,正确编写像以下示例一样的代码:

#![feature(abi_custom)]///使用`Arm`的非标准`ABI`对`两个数字`除法和模数`.
/// ```c
/// typedef struct { int quot; int rem; } idiv_return;
///  __value_in_regs idiv_return __aeabi_idivmod(int num, int denom);
/// ```
//安全:`汇编实现了期望的`ABI`,`"custom"`确保无法`直接调用`此函数.  #[unsafe(naked)]
pub unsafe extern "custom" fn __aeabi_idivmod() {core::arch::naked_asm!("push {{r0, r1, r4, lr}}",//备份垃圾."bl {trampoline}",//为`a/b`调用`"extern"C"`函数."pop {{r1, r2}}","muls r2, r2, r0",//执行模."subs r1, r1, r2","pop {{r4, pc}}",//恢复`clobbers`,通过设置`'pc'`隐式返回.trampoline = sym crate::arm::__aeabi_idiv,);
}

使用自定义调用约定的结果是,不能使用Rust调用式调用此类函数;编译器根本不知道如何为此类调用生成正确的代码.

相反,当程序试调用extern"``自定义"函数时,编译器会出错,执行该函数只能使用内联汇编.

在线汇编上的配置

cfg_asm功能增加了,可用#[cfg(...)]#[cfg_attr(...,...)]注解汇编块的各行的功能.配置汇编的特定部分帮助使汇编依赖目标,目标特征或特征标志等.如:

#![feature(cfg_asm)]
global_asm!(//...如果允许,请初化`SP`.这一般由`CPU`自身或`引导加载器`初化,但在重置目标时,某些`调试器`无法设置它,从而导致栈崩溃.#[cfg(feature = "setsp")]"ldr r0, =_stack_startmsr msp, r0",//...
)

此例来自,当前必须使用在每次使用#[cfg(...)]时复制整个汇编块的自定义宏的cortex-m.有了cfg_asm,将不再需要它.

http://www.dtcms.com/a/520409.html

相关文章:

  • 西安住房建设局网站首页企业网站 设计需求
  • LangChain:让大模型具备思考与行动能力的框架
  • MySQL 及 SQL 注入详细说明
  • 医院移动护理系统源码,JAVA移动护理系统源码,医院移动护士站源码
  • 网站建设营销型新型塑料建筑模板图片
  • Linux 有哪些功能相似的命令
  • 外贸推广网站冲压加工瑞安有做网站吗
  • 【开题答辩实录分享】以《租房小程序的设计和实现》为例进行答辩实录分享
  • vscode debug Transformer源码说明
  • 仓颉语言核心特性深度解析:类型系统与内存安全实践
  • IP 地址 (Internet Protocol Address) 详细介绍
  • PHP网站开发常用函数房城乡建设部网站
  • 开源的SSR框架都是怎么实现的?
  • RLVR训练多模态文档解析模型-olmOCR 2技术方案(模型、数据和代码均开源)
  • AI 领域热门方向或代表性技术/模型
  • MySQL 体系结构、SQL 执行与设计范式
  • 个人网站如何搭建国家企业信用信息网官网
  • MySQL学习之SQL语法与操作
  • “麻烦您了”英语怎么说?
  • 临时上线没有回滚方案会怎样
  • 哪个网站做高仿衣服中小学网站建设建议
  • Linux 中的 DNS 工作原理(二):各级 DNS 缓存
  • vip影视网站如何做app建设电子商务网站的预期收益
  • 从 DeepWalk 到 Node2Vec:如何让图学习“更聪明”?
  • leetcode合并有序链表
  • 知识图谱遇上大语言模型:天作之合还是理想泡影?
  • Kafka入门:基础架构讲解,安装与使用
  • 深圳seo网站推广报价wordpress导航栏的文件在哪
  • 电手术刀VS神经调音师:解密电刺激技术差异
  • lance + duckdb 替代 parquet + pandas