当前位置:网站首页>嵌入汇编-1 格式讲解
嵌入汇编-1 格式讲解
2022-08-03 05:23:00 【SEVENTHD7】
1 内联汇编格式
__asm__ __volatile__("InSTructiON List" : Output : Input : Clobber/Modify);
asm("汇编语句"
:输出寄存器
:输入寄存器
:会被修改的寄存器);说明:
1. _asm_ 是GCC关键字asm的宏定义:#define __asm__ asm
Volatile 通知编译器不要去做优化
2. 输出寄存器 ”= “表示这是输出寄存器
3. 输入寄存器 汇编葱须规定把 输出和输入寄存器 按顺序统一编号,从输出寄存器
序列,从左到右,从上倒下,以0%开始,分别记为 %0、1%、,,,%9
4. 会被修改的寄存器
看个简单的例子,足以说明前3点
asm("leal (%1, %1, 4), %0"
: "=r" (y)
: "0" (x)
);"leal (%1, %1, 4), %0"
表示:汇编指令
: "=r" (y)
表示:"=" 输出,r,动态分配寄存器,寄存器exa输出到 y变量
: "0" (x)
表示:0,%0寄存器,也就是exa, x-->exa
对于说明中的第4点,现在说明下:
有时候,你想通知GCC当前内联汇编语句可能会对某些寄存器或内存进行修改,希看GCC在编译时能够将这一点考虑进往。那么你就可以在Clobber/Modify域声明这些寄存器或内存。
这种情况一般发生在:
1. 一个寄存器出现在"Instruction List",
2. 但却不是由Input/Output操纵表达式所指定的,
3. 也不是在一些Input/Output操纵表达式使用"r"约束时由GCC 为其动态选择的,
4. 同时此寄存器被"Instruction List"中的指令修改,
5. 而这个寄存器只是供当前内联汇编临时使用的情况。
例如:
__asm__ ("mov R0, #0x34" : : : "R0");
寄存器R0出现在"Instruction List中",并且被mov指令修改,但却未被任何Input/Output操纵表达式指定,所以你需要在Clobber/Modify域指定"R0",以让GCC知道这一点。
更详尽的说明
由于你在Input/Output操纵表达式所指定的寄存器,或当你为一些Input/Output操纵表达式使用"r"约束,让GCC为你选择一个寄存器时,GCC对这些寄存器是非常清楚的——它知道这些寄存器是被修改的,你根本不需要在Clobber/Modify域再声明它们。
但除此之外, GCC对剩下的寄存器中哪些会被当前的内联汇编修改一无所知。
所以假如你真的在当前内联汇编指令中修改了它们,那么就最好在Clobber/Modify 中声明它们,让GCC针对这些寄存器做相应的处理。否则有可能会造成寄存器的不一致,从而造成程序执行错误。
我们参看内存被修改的情况,寄存器中的值没有及时更新,类似于 volatile 功能:
假如一个内联汇编语句的Clobber/Modify域存在"memory",那么GCC会保证在此内联汇编之前,假如某个内存的内容被装进了寄存器,那么在这个内联汇编之后,假如需要使用这个内存处的内容,就会直接到这个内存处重新读取,而不是使用被存放在寄存器中的拷贝。由于这个 时候寄存器中的拷贝已经很可能和内存处的内容不一致了。
例如:
int main(int __argc, char* __argv[])
{
int* __p = (int*)__argc;
(*__p) = 9999;
__asm__("":::"memory");
if((*__p) == 9999)
return 5;
return (*__p);
}
本例中,假如没有那条内联汇编语句,那个if语句的判定条件就完全是一句空话。GCC在优化时会意识到这一点,而直接只生成return 5的汇编代码,而不会再增添if语句的相关代码,而不会生成return (*__p)的相关代码。
但你加上了这条内联汇编语句,它除了声明内存变化之外,什么都没有做。但GCC此时就不能简单的以为它不需要判定都知道 (*__p)一定与9999相等,因为内存发生了变化。它只有老老实实执行这条if语句的汇编代码,一起相关的两个return语句相关代码。
边栏推荐
- 中国认证认可服务行业“十四五”发展规划及经营模式分析报告2022~2028年
- 【 Nmap and Metasploit common commands 】
- opencv透视变化
- mysql 客户端SSL错误2026 (HY000)
- 自监督论文阅读笔记 Self-supervised Label Augmentation via Input Transformations
- Ansible installation and deployment detailed process, basic operation of configuration inventory
- 磁盘空间管理
- 极光推送 能否缓存 消息
- Oracle 日历表详解(含节假日)
- 中国融资租赁行业市场投资分析与前景战略规划建议报告2022~2028年
猜你喜欢

HoloLens联合发明人:打造理想的全天AR需要解决这些问题

自监督论文阅读笔记 Self-supervised Label Augmentation via Input Transformations

Oracle 密码策略详解

MySQL 下载和安装详解
ASP.NET MVC3的伪静态实现

用iPhone前摄3D人像建模,Meta:我看行

自监督论文阅读笔记 Multi-motion and Appearance Self-Supervised Moving Object Detection

The ` monorepo ` ` hoist ` mechanism lead to the change of the loading configuration file path

自监督论文阅读笔记 Incremental-DETR:Incremental Few-Shot Object Detection via Self-Supervised Learning

【第四周】MobileNet和HybridSN
随机推荐
网络间通信
【第四周】MobileNet和HybridSN
Mysql 存储过程详解(procedure)
中国磷化铟晶圆行业发展前景与投资规划分析报告2022~2028年
中国石油行业并购重组趋势与投资战略规划建议报告2022~2028年
The ` monorepo ` ` hoist ` mechanism lead to the change of the loading configuration file path
page fault-页异常流程
解决Gradle Download缓慢的百种方法
MySql 怎么查出符合条件的最新的数据行?
自监督论文阅读笔记DisCo: Remedy Self-supervised Learning on Lightweight Models with Distilled Contrastive
Try setting CHROME_EXECUTABLE to a Chrome executable
中国生活服务O2O行业发展现状与市场规模预测报告2022~2028年
卷积神经网络入门
详解背包问题(DP分支)
Kotlin 中的泛型介绍
C# 数组之回溯法
3588. 排列与二进制
Hook初探索
用iPhone前摄3D人像建模,Meta:我看行
spark sql 报错 Can‘t zip RDDs with unequal numbers of partitions