C语言与汇编混合编程

时间:2021-04-04 01:11:35

作者:郭孝星
微博:郭孝星的新浪微博
邮箱:allenwells@163.com
博客:http://blog.csdn.net/allenwells
Github:https://github.com/AllenWells

通常情况下,以下几种情况必须使用内嵌汇编:

  • 程序中使用饱和算术运算,如SSAT16和SUAT16指令。
  • 程序中需要对协处理器进行操作。
  • 在C程序中完成对程序状态寄存器的操作。

一 内联汇编语法

1.1 格式


#
#
# constraint定义variable的存放位置
# r——使用任何可用的通用寄存器
# m——使用变量的内存地址
#
# output修饰符
# +——可读可写
# =——只写
# S——该输出操作数不能使用输入部分使用过的寄存器,只能用“+s”或“- s”的方式使用。
#
#
asm volatile (“asm code”
:output
:”constraint” (variable)

:input
:”constranit” (variable/immediate)

# constraint定义variable/immediate的存放位置
# r——使用任何可用的通用寄存器(变量和立即数都可以使用)
# m——使用变量的内存地址(不能用立即数)
# i——使用立即数(不能使用变量)
:changed
);


__asm__(
"mov r0,%0\n\t"
"add %0,%1,%2\n\t"
:"=r"(sum) // 输出参数列表 (返回值)
:"r"(a),"r"(b) // 输入参数列表(函数的参数输入) %0表示的是输出和输入参数列表的第一个参数 sum,%1 表示a, %2表示b
:"r0" // 被更改资源列表
// r 表示的使用寄存器存储这个参数
// I 表示是一个立即数
/数据库的三级模式/ M 表示的是一个有效的内存地址
// + 被修饰的参数具有可读可写
// = 被修饰的参数只可以写
// 无 被修饰的参数只读

);

三 volatile关键字的使用

volatile关键字声明的变量表明该变量容易发生变化,与该变量的运算,不要进行编译优化,以免出错。

Volatile关键字的使用场合如下所示:

  • 中断服务程序修改的供其他程序检测的变量需要volatile。
  • 多任务环境下的任务间共享的标志需要加volatile。
  • 存储器映射的硬件寄存器需要加volatile,因为每次对它读写都可能有不同意义。

四 GNU汇编器的平台无关伪指令

汇编伪指令:该指令既不控制机器的操作也不被汇编成机器代码,他只是指导汇编程序如何进行。

4.1 符号定义伪指令

C语言与汇编混合编程

4.2 数据定义伪指令

C语言与汇编混合编程

4.3 汇编控制伪操作

4.3.1 程序执行控制指令

.if   logical-expression         //用于决定指令执行流程的逻辑表达式
……
.else
……
.endif

该指令可以嵌套调用。

4.3.2 宏指令

.macro  macroname  macargs      //macroname 宏名   macargs 宏指令参数当宏指令被展开时替换成相应的值,类似于函数的传参
.code
.endm

五 杂项伪操作

.align  abs-expr               //对齐表达式
.align 2
.string “abcde” //声明后面字符串的对齐方式位4字节对齐,该字符串占8字节的存储空间
.section sectionname //定义一个段
.extern symbol //声明一个外部符号(区分大小写),用于兼容性其他汇编
.weak symbol //声明一个符号是弱符号,如果这个符号没有定义,编译会忽略,而不会报错。