arm64--内嵌汇编

news2024/12/24 20:20:33

内嵌汇编代码基本用法

1.作用:对于特定重要和时间敏感的代码进行优化,同时在C语言中访问某些特殊指令(例如内存屏障指令)来实现特殊功能
2.内嵌汇编代码主要有两种形式
基础内嵌汇编代码:不带任何参数
扩展内嵌汇编代码:可以带输入输出参数
3.扩展内嵌汇编代码

asm 修饰词( 
指令部分
:输出部分 //可以为空
:输入部分 //可以为空
:损坏部分)//"cc":寄存器改变 "memory":
  1. 各部分解释
    修饰词:
    volatile 用于关闭GCC优化
    inline 用于内联,GCC会把汇编代码编译为尽可能短的代码
    goto 用于内嵌汇编跳转到C语言的标签里面
    输出部分用于描述在指令部分中可以修改的C语言变量以及约束条件。
    输出约束通常以“=”或者“+”号开头,然后是一个字母(表示对操作数类型的说明),接着是关于变量结合的约束。“=”表示被修饰的操作数只具有可写属性;“+”表示被修饰的操作数只具有可读、可写属性。
    输出部分可以为空
    输入部分用来描述在指令部分只能读取的C语言变量以及约束调试。输入部分描述的参数只具有可读属性,不要试图修改输入部分的参数内容,因为GCC假定输入部分的参数在内嵌汇编之前和之后都是一致的。
    在输入部分中不能使用“=”或者“+”约束条件,否则编译器会报错。
    输入部分可以为空
    损坏部分一般以“memory”结束
    “memory”告诉GCC,如果内联汇编代码改变了内存中的值,那么让编译器做如下优化;在执行完汇编代码后重新加载该值,目的是放置编译乱序。
    “CC”表示内嵌代码修改了状态寄存器的相关标志位,例如,使用CNBZ等比较语句。
    当输入部分和输出部分显式地使用了通用寄存器时,应该在损坏部分明确告诉编译器,编译器在选择使用哪个寄存器来表示输入和输出操作数时,不会使用损坏部分里声明的任何寄存器,以免冲突。
    指令部分,在内嵌汇编代码中使用%0来表示输出部分和输入部分的第一个参数,%1表示第二个参数,以此内推。

内嵌汇编代码的修饰符和约束符

1.内嵌汇编代码的常见修饰符
在这里插入图片描述
2. 内嵌汇编代码的常见约束符

3.ARM64体系结构中特有的约束符
在这里插入图片描述

使用汇编符号名

int add(int i,int j)
{
    int res =0;
    asm volatile (
    "add %w[result], %w[input_i], %w[input_j]"
    :[result] "=r" (res)
    :[input_i]"r"(i)  [input_j]"r"(j)
    );
    
    return res;
}

先看输出部分,其中只定义了一个操作数。“result”定义了一个汇编符号操作数,符号名为result,它对应“=r”(res),并使用了函数中定义的 res 变量,在汇编代码中对应%w[resul]中,w表示ARM64中的32位通用寄存器。再看输入部分,其中定义了两个操作数。同样使用定义汇编符号操作数的方式来定义。第1个汇编符号操作数是 input_i ,对应的是函数形参i,第2个汇编符号操作数是 input_j,对应的是函数形参j。

内嵌汇编函数与宏的结合

1.内嵌汇编函数与C 语言宏可以结合起来使用,让代码变得高效和简洁。我们可以巧妙地使
用C语言宏中的“#”以及“##”符号。若在宏的参数前面使用“#”,预处理器会把这个参数转换为一个字符串。“##”用于连接参数和另一个标识符,形成新的标识符。

#define ATOMIC_OP(op,asm_op) 
static inline void atomic_##op(int 1, atomict *v)
{
     register int w0 asm ("w0")= i;
     register atomic_t *xl asm ("xl")=v; 
     asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(op),
     " "#asm_op "%w[1], %[v]\n")
     : [i] "+r"(w0), [v] "+Q"(v->counter)
     :"r"(X1)
     :__LL_SC_CLOBBERS);
}
ATOMIC_OP(andnot, stclr)
ATOMIC_OP(or, stset)
ATOMIC_OP(xor, steor)
ATOMIC_OP(add, stadd)

使用goto修饰词

asm goto (
指令部分
:/*输出部分为空*/
:输入部分
:损坏部分
:Goto Labels)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2076755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ES6新特性】介绍ES6新特性的内容,如var,Let,Const声明变量的区别,解构赋值的概念,字符串的扩展,数组的扩展,以及对象的扩展。

目录 1.var,let,const的区别 1.1 var 1.2 let 1.3 const 1.4 区别总结 2.解构赋值 2.1 基本解构化赋值 2.2 数组取值 2.3 对象解构化赋值和取值 2.4 Math对象的解构化使用 3. 字符串扩展 3.1 新增字符串遍历方式 3.2 模版字符串 3.3 字符串…

数据库学习笔记

一、数据库相关概念 主流的关系型数据库管理系统(DBMS) 关系型数据库以 表格 的形式存在,以 行和列 的形式存取数据,关系型数据库这一系列的行和列被称为表,无数张表组成了 数据库 ,常见的关系型数据库有 …

绿色积分引领:我店平台的可持续消费革命

在当今数字化浪潮的推动下,“我店”凭借其创新的环保积分系统,在消费市场中脱颖而出,逐渐改变着市场的结构。本文将详细分析该平台的竞争优势、市场策略以及它如何利用创新手段塑造未来的消费趋势。 一、环保积分:消费体验革新的关…

在ElementUI项目中集成iconfont图标库

在前端项目开发中经常会遇到使用的组件库提供的ICON图标不够用的情况。最常见的解决方案无非就是把设计图的图标切图引入到项目中。还有就是使用svg图标,封装一个渲染组件在项目里面直接引入这个组件。 本文将介绍另一种方法,即集成iconfont图标库的图标…

redis面试(二十二)读锁释放

假设现在已经有各种锁的重入什么的,那如何释放锁? 读锁读锁 假如说,同一个线程多次加读锁,或者不同的线程加了多个读锁 当前的锁结构长这样 anyLock: { “mode”: “read”, “UUID_01:threadId_01”: 2, “UUID_02:threadId_02…

CRUD的最佳实践,联动前后端,包含微信小程序,API,HTML等(二)

CRUD老生常谈,但是我搜索了一圈,发觉几乎是着重在后端,也就是API部分! 无外乎2个思路 1.归总的接口,比如一个接口,实现不同表的CRUD 2.基于各自的表,使用代码生成器实现CRUD 个人来说是推荐2&am…

css设置input单选radio多选checkbox样式

最近接手一个古老的项目,要修改里边的主题颜色,使用css的var方法一路轻松,最后在input的单选radio和多选checkbox被踩了刹车,也是有几年没做这种原始的项目手生了,最后经过几番折腾后,通过input的伪元素将其…

FPGA开发——使用verilog实现异步FIFO

一、FIFO 介绍 1、FIFO的分类 FIFO ( First In First Out)先进先出存储器。根据接入的时钟信号,可以分为同步 FIFO 和异步 FIFO 。 FIFO 底层是基于双口 RAM ,同步 FIFO 的读写时钟一致,异步 FIFO 读时钟和…

一看就会的Mysql 集群技术

目录 一、Mysql介绍 1.1什么是MySQL 1.2MySQL的优势 1.3MySQL的常用语句 二、MySQL源码安装 三、实验练习 3.1MySQL部署 实验环境 实验步骤 1.创建用户,数据目录,更改权限 2.修改文件 3.初始化,会生成一个密码,将其保…

没有人会窃取你的想法,关键在于执行

没有人会窃取你的想法,关键在于执行 引言 当我第一次读到 Pieter Levels 的创业故事时,我感到无比激动和鼓舞。那种看到未来无限可能的感觉,让我充满了希望与奋斗的力量。他的经历不仅让我明白了创意的价值,更重要的是让我深刻感…

内网穿透的几种方法

内网穿透的几种方法 随着网络技术和应用的不断发展,越来越多的企业和个人需要实现内外网之间的数据交互和服务访问。然而,由于防火墙、NAT(网络地址转换)等安全措施的存在,直接从外部访问内部网络中的服务器或设备变得…

Linux基础软件-dns(一)

作者介绍:简历上没有一个精通的运维工程师。希望大家多多关注作者,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux进阶部分又分了很多小的部分,我们刚讲完了Linux日常运维。讲的那些东西都算是系统自带的,但是Linux作为一个…

Nvidia驱动莫名其妙不好使了?nvidia-smi报错?如何解决?已解决!!

文章目录 一、报错提示二、解决方案2.1 原因1的解决办法2.2 原因2的解决方案 一、报错提示 Ubuntu20.04出现Failed to initialize NVML: Driver/library version mismatch问题NVIDIA-SMI has failed because it couldn‘t communicate with the NVIDIA driver. 二、解决方案 …

深入探究linux文件IO

一、原子操作和竞争条件 所有系统调用都是以原子操作方式执行的。之所以这么说,是指内核保证了某系统调用中的所有步骤会作为独立操作而一次性加以执行,其间不会为其他进程或线程所中断。 以独占方式创建一个文件 结合 O_CREAT 和 O_EXCL 标志来一次性…

AI学习记录 - 怎么理解 torch 的 torch.nn.BatchNorm2d

画图不易,有用就点个赞 这里创建了一个随机张量,形状为 (4, 3, 4, 4),分别对应 形状为 (batch_size, num_channels, height, width) batch_size:批次 num_channels: 通道(什么是通道看上一章节&#xff0…

串口和RS485通信

一、 定义串口收发数据结构体 /*COM Received Data Structure*/ typedef struct {uint8_t ubr_EndFlag; //Received data end flag uint8_t ubr_buffer[300]; //Received data bufferuint8_t ubr_bufferTemp[300]; //Received data bu…

K-medoids算法原理及Python实践

一、原理 K-medoids算法是一种聚类算法,它的原理与K-Means算法相似,但关键区别在于它使用数据集中的实际点(称为medoids)作为簇的中心点,而不是像K-Means那样使用簇内所有点的平均值。以下是K-medoids算法的主要原理&…

如何在算家云搭建模型Stable-Fast-3D(3D模型生成)

一、模型介绍 Stable-Fast-3D 具有 UV 展开和照明解缠的稳定快速 3D 网格重建,它是一种从单个图像进行快速前馈 3D 网格重建的最先进的开源模型。 二、模型搭建流程 基础环境最低要求说明: 环境名称版本信息1Ubuntu22.04.4 LTSCudaV12.1.105Python3.…

【项目日记】高并发内存池 ---项目介绍及组件定长池的实现

余生还长,你别慌,也别回头,别念旧. --- 余华 --- 1 高并发内存池简介 高并发内存池项目是实现一个高并发的内存池,他的原型是google的一个开源项目tcmalloc,tcmalloc全称Thread-Caching Malloc,即线程缓存…

快速排序与其例题

一、快速排序 1、简单介绍:快速排序(Quick Sort)是一种高效的排序算法,由计算机科学家Tony Hoare在1960年提出。它是基于分治法的排序算法,其基本思想和步骤如下: 基本概念 快速排序的核心思想是将待排序…