- 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)