在C代码中嵌入汇编指令.docVIP

  • 7
  • 0
  • 约3.53千字
  • 约 7页
  • 2018-01-01 发布于河南
  • 举报
在C代码中嵌入汇编指令 标 题: 在C代码中嵌入汇编指令 发信站: BBS 水木清华站 (Fri Apr 11 19:53:30 2003), 转信 在C代码中嵌入汇编指令 --转贴自21IC中国电子网AVR单片机论坛 hudaidai 发表于 6/27/2002 5:58:22 PM (此文和《如何使用AVRGCC》原来在一起,太长了贴不上。经过我的重新编排以便于初学 者参考,在我下载的地方已经原作者不可考了。功劳属于原作者,修改编排后产生的错误 由hudaidai负责) 在C代码中嵌入汇编指令 一.GCC的ASM声明 首先看一个从PORTD读入数据的例子: asm(in %0, %1 : =r(value) : I(PORTD) : ); 由上可以看出嵌入汇编的4个部分: 1. 汇编指令本身,以字符串in %0, %1表示; 2. 由逗号分隔的输出操作数,本例为=r(value) 3. 由逗号分隔的输入操作数,本例为I(PORTD) 4. Clobber寄存器 嵌入汇编的通用格式为: asm(code : output operand list : input operand list : clobber list); 例子中%0表示第一个操作数,%1表示第二个操作数。即: %0 - =r(value) %1 - I(PORTD) 如果在后续的C代码中没有使用到汇编代码中使用的变量,则优化编译时会将这些语句删 除。为了防止这种情况的发生,需要加入volatile属性: asm volatile (in %0, %1 : =r(value) : I(PORTD) : ); 嵌入汇编的的Clobber寄存器部分可以忽略,而其他部分不能忽略,但可以为空。如下例 : asm volatile(cli : :); 二.汇编代码 用户可以在C代码里嵌入任意的汇编指令,就如同在汇编器里写程序一样。AVR-GCC提供了 一些特殊的寄存器名称: 符号 寄存器 __SREG__ 状态寄存器SREG(0x3F) __SP_H__ 堆栈指针高字节(0x3E) __SP_L__ 堆栈指针低字节(0x3D) __tmp_reg__ r0 __zero_reg__ r1。对于C代码而言其值永远为0 三.输入/输出操作数 约束符号 适用于 范围 a r16~r23 b 指针 Y,Z d r16~r31 e 指针 X,Y,Z G 浮点常数 0.0 I 6比特正常数 0~63 J 6比特负常数 -63~0 l r0~r15 M 8比特正常数 0~255 N 整数常数 -1 O 整数常数 8,16,24 P 整数常数 1 r r0~r31 t R0 W 寄存器对 r24,r26,r28,r30 X 指针X r27:r26 Y 指针Y r29:r28 Z 指针Z r31:r30 要注意的是,在使用这些约束符号时要防止选择错误。例如,用户选择了r约束符号, 而汇编语句则使用了ori。编译器可以在r0~r31之间任意选择寄存器。若选择了r2~r15 ,则会由于不适用ori而出现编译错误。此时正确的约束符应该是d。 约束符号还可以有前置修饰符,如下表所示。 修饰符 指定 = 只写操作数 + 读-写操作数(嵌入汇编不支持) 寄存器只能用做输出 输出操作数必须为只写操作数,C表达式结果必须为l(r0~r15)。编译器不检查汇编指令 中的变量类型是否合适。 输入操作数为只读。如果输入/输出使用同一个寄存器怎么办呢?此时可以在输入操作数 的约束字符里使用一个一位数字来达到这个目的。这个数字告诉编译器使用与第n个(从0 开始计数)操作数相同的寄存器。例如: asm volatile(SWAP %0 : =r(value) : 0(value)); 这条语句的目的是交换变量value的高低4位。约束符号0告诉编译器使用与第一个操作 数相同的寄存器作为输入寄存器。要注意的是,即使用户没有指定,编译器也有可能使用 相同的寄存器作为输入/输出。在某些情况下会引发严重的问题。如果用户需要区分输入/ 输出寄存器,则必须为 输出操作数增加修饰符。如下例所示。 asm volatile(in %0, %1; out %1, %2 : =r(input) : I(port), r(output) ); 此例的目的是读入端口数据,然后给端口写入另一个数据。若编译器不幸使用了同一个寄 存器作为参数input和output存储位置,则第一条指令执行后output的内容就被破坏了。 而用了修饰符之后,这个问题得以解决。 下面为一个高16位与低16位交换的32位数据操作的例子: asm volatile(mov __tmp_reg__, %A0; mov %A0, %D0; mov %D0, __t

文档评论(0)

1亿VIP精品文档

相关文档