当前位置:网站首页>嵌入汇编-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语句相关代码。
边栏推荐
猜你喜欢

Convolutional Nerual Nertwork(CNN)

自监督论文阅读笔记 TASK-RELATED SELF-SUPERVISED LEARNING FOR REMOTE SENSING IMAGE CHANGE DETECTION

自监督论文阅读笔记 Multi-motion and Appearance Self-Supervised Moving Object Detection
深度学习理论课程第八、九、十章总结

自监督论文阅读笔记 S3Net:Self-supervised Self-ensembling Network for Semi-supervised RGB-D Salient Object Det

经典论文-ResNet
代码没写完,哪里有脸睡觉!17 张程序员壁纸推荐

Ansible installation and deployment detailed process, basic operation of configuration inventory

Qlik Sense 字符串截取和拼接详解(Left、Right、&)

神经网络之感知机
随机推荐
Execute the mysql script file in the docker mysql container and solve the garbled characters
MySQL 排序
【第三周】ResNet+ResNeXt
3559. 围圈报数
自监督论文阅读笔记Index Your Position: A Novel Self-Supervised Learning Method for Remote Sensing Images Sema
时间盲注脚本
理论上的嵌入式跑马灯
C# 数组之回溯法
Android学习 | 08.SQLiteOpenHelper
代码没写完,哪里有脸睡觉!17 张程序员壁纸推荐
深度学习理论课程第八、九、十章总结
自监督论文阅读笔记FIAD net: a Fast SAR ship detection network based on feature integration attention and self
softmax和最大熵
详解背包问题(DP分支)
spark sql 报错 Can‘t zip RDDs with unequal numbers of partitions
MySql 怎么查出符合条件的最新的数据行?
漫谈Map Reduce 参数优化
mysql 客户端SSL错误2026 (HY000)
MMU 介绍-[TBL/page table work]
【源码解读】你买的NFT到底是什么?