在 C语言中,如何通过 asm 关键字嵌入汇编语言代码?
一、基本 asm 格式
1. 语法规则
2. test1.c 插入空指令
3. test2.c 操作全局变量
4. test3.c 尝试操作局部变量
二、扩展 asm 格式
1. 指令格式
2. 输出和输入操作数列表
3. test4.c 通过寄存器操作局部变量
4. test5.c 声明使用的寄存器
三、使用占位符来代替寄存器名称
1. test6.c 使用占位符代替寄存器名
2. test7.c 给寄存器起别名
四、使用内存地址
1. test8.c 使用内存地址来操作数据
五、总结
在 Linux 代码中,经常可以看到在 C 代码中,嵌入部分汇编代码,这些代码要么是与硬件体系相关的,要么是对性能有关键影响的。
在很久以前,我特别惧怕内嵌汇编代码,直到后来把汇编部分的短板补上之后,才彻底终结这种心理。
也许你在工作中,几乎不会涉及到内嵌汇编代码的工作,但是一旦进入到系统的底层,或者需要对时间关键场景进行优化,这个时候你的知识储备就发挥重要作用了!
这篇文章,我们就来详细聊一聊在 C 语言中,如何通过 asm 关键字来嵌入汇编语言代码,文中的 8 个示例代码从简单到复杂,逐步深入地介绍内联汇编的关键语法规则。
希望这篇文章能够成为你进阶高手路上的垫脚石!
PS:
示例代码中使用的是 Linux 系统中 AT&T 汇编语法;
一、基本 asm 格式
gcc 编译器支持 2 种形式的内联 asm 代码:
基本 asm 格式:不支持操作数;
扩展 asm 格式:支持操作数;
1. 语法规则
asm [volatile] ("汇编指令")
所有指令,必须用双引号包裹起来;
超过一条指令,必须用分隔符进行分割,为了排版,一般会加上 ;
多条汇编指令,可以写在一行,也可以写在多行;
关键字 asm 可以使用 asm 来替换;
volatile 是可选的,编译器有可能对汇编代码进行优化,使用 volatile 关键字之后,告诉编译器不要优化手写的内联汇编代码。
2. test1.c 插入空指令#include <stdio.h>
int main()
{
asm ("nop");
printf("hello");
asm ("nop nop "
"nop");
return 0;
}
注意:C语言中会自动把两个连续的字符串字面量拼接成一个,所以"nop nop " "nop" 这两个字符串会自动拼接成一个字符串。
生成汇编代码指令:
gcc -m32 -S -o test1.s test1.c
test1.s 中内容如下(只贴出了内联汇编代码相关部分的代码):
#APP
# 5 "test1.c" 1
nop
# 0 "" 2
#NO_APP
// 这里是 printf 语句生成的代码。
#APP
# 7 "test1.c" 1
nop
nop
nop
# 0 "" 2
#NO_APP
可以看到,内联汇编代码被两个注释(#APP ... #NO_APP)包裹起来。在源码中嵌入了两个汇编代码,因此可以看到 gcc 编译器生成的汇编代码中包含了这两部分代码。
这 2 部分嵌入的汇编代码都是空指令 nop,没有什么意义。
3. test2.c 操作全局变量
在 C 代码中嵌入汇编指令,目的是用来计算,或者执行一定的功能,下面我们就来看一下,如何在内联汇编指令中,操作全局变量。
#include <stdio.h>
int a = 1;
int b = 2;
int c;
int main()
{
asm volatile ("movl a, %eax "
"addl b, %eax "
"movl %eax, c");
printf("c = %d ", c);
return 0;
}
关于汇编指令中编译器的基本知识:
eax, ebx 都是 x86 平台中的寄存器(32位),在基本asm格式中,寄存器的前面必须加上百分号%。
32 位的寄存器 eax 可以当做 16 位来使用(ax),或者当做 8 位来使用(ah, al),本文只会按照 32 位来使用。
代码说明:
movl a, %eax // 把变量a的值复制到 %eax 寄存器中;
addl b, %eax // 把变量 b 的值 与 %eax 寄存器中的值(a)相加,结果放在 %eax 寄存器中;
movl %eax, c // 把 %eax 寄存器中的值复制到变量 c 中;
生成汇编代码指令:
gcc -m32 -S -o test2.s test2.c
test2.s 内容如下(只贴出与内联汇编代码相关部分):
#APP
# 9 "test2.c" 1
movl a, %eax
addl b, %eax
movl %eax, c
# 0 "" 2
#NO_APP
可以看到,在内联汇编代码中,可以直接使用全局变量 a, b 的名称来操作。执行 test2,可以得到正确的结果。
思考一个问题:为什么在汇编代码中,可以使用变量a, b, c?
图片新闻
最新活动更多
-
11月22日立即报名>> 【线下论坛】华邦电子与莱迪思联合技术论坛
-
即日-11.30免费预约申请>>> 燧石技术-红外热成像系列产品试用活动
-
11月30日立即试用>> 【有奖试用】爱德克IDEC-九大王牌安全产品
-
即日-12.26火热报名中>> OFweek2024中国智造CIO在线峰会
-
限时免费下载立即下载 >>> 2024“机器人+”行业应用创新发展蓝皮书
-
即日-2025.8.1立即下载>> 《2024智能制造产业高端化、智能化、绿色化发展蓝皮书》
推荐专题
- 1 格力联手优傲!协作机器人领域风云将起?
- 2 同源共创 模式革新 | 华天软件皇冠CAD(CrownCAD)2025新品发布会圆满举行
- 3 回顾 | OFweek 2024智能制造与半导体、印刷包装融合创新大会圆满落幕!
- 4 上海国际嵌入式展暨大会(embedded world China )与多家国际知名项目达成合作
- 5 iEi威强电新品丨IMBA-AM5:工业计算的强劲引擎
- 6 史上首次,大众终于熬不住开启40亿降本计划!关3个工厂,裁员万名...
- 7 守护绿色学习空间,EK超低温热泵服务对外经济贸易大学图书馆
- 8 颜值高 有“门”道|贝特威汽车门板内饰AI视觉检测解决方案
- 9 现场直击 | 维科网带你逛 VisionChina2024(深圳),领略机器视觉盛宴!
- 10 观众登记启动 优解制造未来,锁定2025 ITES深圳工业展
发表评论
请输入评论内容...
请输入评论/评论长度6~500个字
暂无评论
暂无评论