arm64--内嵌汇编

内嵌汇编代码基本用法

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.内嵌汇编代码的常见修饰符

  1. 内嵌汇编代码的常见约束符

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)
相关推荐
用余生去守护18 分钟前
python报错系列(16)--pyinstaller ????????
开发语言·python
数据小爬虫@22 分钟前
利用Python爬虫快速获取商品历史价格信息
开发语言·爬虫·python
向宇it24 分钟前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
莫名其妙小饼干41 分钟前
网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
java·开发语言·maven·mssql
十年一梦实验室1 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
最爱番茄味1 小时前
Python实例之函数基础打卡篇
开发语言·python
Uu_05kkq1 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法
Oneforlove_twoforjob2 小时前
【Java基础面试题033】Java泛型的作用是什么?
java·开发语言
engchina2 小时前
如何在 Python 中忽略烦人的警告?
开发语言·人工智能·python
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎