64位系统--GNU_C
GNU C内嵌汇编语言
GNU C语言提供了关键字asm来声明代码是内嵌的汇编语句
如:
1
C语言使用关键字__asm__和__volatile__对汇编语句进行修饰,这两个关键字在C语言内嵌汇编语句时经常使用
- __asm__:用于声明这行代码是一个内嵌汇编表达式
- __volatile__:其作用是告诉编译器此行代码不能被编译器优化
GNU C语言有着极其复杂的书写格式,将分为3个部分学习
内嵌汇编表达式
操作约束和修饰符
序号占位符
内嵌汇编表达式
- GNU
C语言的内嵌汇编表达式由4部分构成,它们之间使用“:”号分割,其完整格式为
- 指令部分 : 输出部分 : 输入部分 : 损坏部分
- 如果将内嵌汇编表达式当作函数,指令部分是函数中的代码,输入部分用于向函数传入参数,输出部分可理解为函数的返回值。
4个部分的详细解释:

损坏部分的3种通知:
- 寄存器修改通知
- 内存修改通知
- 标志寄存器修改通知
操作约束和修饰符
每个输入,可细分为:
- 寄存器约束
- 内存约束
- 立即数约束
在输出表达式中,还有限定寄存器操作的修饰符
- 详细解释:



- 修饰符
- &


序号占位符
- 定义:是输入/输出操作约束的数值映射
- 每个内嵌汇编表达式最多只有10条输入/输出约束,这些约束按照书写顺序依次被映射为序号0~9
- 如果指令部分想引用序号占位符,必须使用百分号%前缀加以修饰
- 如%0表示第一个操作约束
- 为了区分序号占位符和寄存器,特别使用两个百分号(%%)来对寄存器加以修饰
- 在%与序号占位符之间插入字母b表示操作最低字节,或插入字母h表示操作次低字节
GNU C语言对标准C语言的扩展
GNU C语言在标准C语言的基础上引入了诸多人性化的扩展
柔性数组成员(或称零长数组、变长数组 )
- GNU C语言允许使用长度为0的数组来增强结构体的灵活性,其在动态创建结构体时有着非常明显的优势
case关键字支持范围匹配
GNU C语言允许case关键字匹配一个数值范围,由此可以取代多级的if条件检测语句
1
2case 'a'...'z':
break;
typeof关键字获取变量类型
- 借助关键字typeof(x)可以取得变量x的数据类型
可变参数宏
- 在GNU C语言中宏函数允许使用可变参数类型

元素编号
- 标准C语言规定数组和结构体必须按照固定顺序对成员(或元素)进行初始化赋值
- GNU C语言为使数组和结构体初始化更加自由,特意放宽该限制
- 数组可以在初始化期间借助下标对某些元素进行赋值,并在结构体初始化过程中使用成员名直接对成员进行赋值
- 允许数组和结构体按照任意顺序对成员(或元素)进行初始化赋值
当前函数名
- 为当前函数的名字准备了两个标识符
- __PRETTY__FUNCTION__:保存着带有语言特色的名字
- __FUNCTION__:保存着函数在源码中的名字
- 在C函数中,这两个标识符代表的函数名字相同
- 为当前函数的名字准备了两个标识符
特殊属性声明
- 允许使用特殊属性对函数、变量和类型加以修饰,以便对它们进行手工代码优化和定制
- 在声明处加上关键字__attribute__((ATTRIBUTE))即可指定特殊属性
- 关键字中的ATTRIBUTE是属性说明
- 如有多个属性,必须用逗号隔开
- 目前支持的属性说明有

- noreturn属性用来修饰函数,表示该函数从不返回,会使编译器在优化代码时剔除不必要的警告信息
- packed属性作用是取消结构在编译时的对齐优化,使其按照实际占用字节数对齐
- regparm(n)属性用于以指定寄存器传递参数的个数,该属性只能用在函数定义和声明里
- 寄存器参数的上限值为3(使用顺序为EAX、EDX、ECX),若超过3,剩余参数将使用内存传递方式
- 该属性只在x86处理器体系结构下有效
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yeの博客!