#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9")
在U-Boot的源码中,使用了寄存器r9来表示全局数据结构gd。
那么,到底应该如何定义一个寄存器变量呢?从GCC的使用手册中可知,定义如下:
register int *foo asm ("reg");
其中register关键字是必须的,asm ("reg")为嵌入式汇编,表示用reg寄存器存储gd指针,reg和CPU体系结构相关。需要注意的是,不能使用static const 和volatile等限定符,否则,预期可能与你设想的相反。特别需要主要的是volatile,就算加了也是阻止不了编译器优化的(U-Boot的定义是不符合GCC编译器规范的,如果你用grep DECLARE_GLOBAL_DATA_PTR -nr 命令在U-Boot源码中查找,你就会发现,有的定义就没有volatile)。
定义寄存器变量,单有上面的定义还是不行的。因为,你虽然申明了使用reg来表示foo指针,但编译器还是会是使用reg去作其他的用途(参数传递等等)。如果想让编译器不使用reg寄存器作其他用途,则还需要使用‘-ffixed-reg’ 编译选项告诉编译器reg寄存器是固定用途寄存器。
在arch/arm/config.mk文件中,可以找到‘-ffixed-reg’选项(U-Boot使用了r9寄存器):
PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \
-fno-common -ffixed-r9