对于我正在研究的项目,我使用魔术数字。 该宏用于定义一个
#define BOOTSIGNATURE 0xAA55
然而,当我HEXDUMP生成的文件时,它应该说AA55它说55 AA。
海湾合作委员会是否会混淆字数,或者是我?该项目适用于x86处理器。 AA 55需要按特定顺序排列。我可以只交换字节,但我很好奇为什么GCC这样做。
答案 0 :(得分:2)
0xAA55
是int
,因此您需要遵守机器的字节顺序。我将它存储为char数组:
const unsigned char BOOTSIGNATURE[] = {0xAA, 0x55};
答案 1 :(得分:2)
预编译器宏不会显示在编译的目标文件中 - 编译器根本看不到它们。如果您只是拥有#define
并且从未在任何地方使用它,那么就没有任何痕迹。
如果您在代码中使用它,它可能会在指令中显示为常量(例如,将常量加载到寄存器或内存中)。如果您使用它来初始化静态数据,它将在数据段中显示为常量:
// Global variable definition
#define BOOTSIGNATURE 0xAA55
uint16_t my_global = BOOTSIGNATURE;
如果您编译上面的内容并查看数据段,它看起来像这样:
$ gcc -c test.c
$ objdump -s test.o
[...]
Contents of section .data:
0000 55aa0000 U...
如您所见,这两个字节以小端顺序55 AA
存储在内存中(前导0000
是以十六进制表示的段偏移量。)
如果要控制数据的字节顺序,则将其存储为显式字节数组:
uint8_t my_global[] = {0xAA, 0x55};
这将始终按指定的顺序存储字节。
答案 2 :(得分:0)
如果要编写可移植代码,则可以使用函数强制执行给定的字节顺序。例如,these functions允许您将本机host-byte-order中的16位值转换为big-endian或little-endian,具体取决于文件中所需的顺序。
#define BOOTSIGNATURE 0xAA55
struct bootheader {
uint16_t signature_be;
} header;
header.signature_be = htobe16( BOOTSIGNATURE);
我喜欢在非主机字节顺序的变量和结构元素上使用_le
或_be
后缀。
由于你需要big-endian,你可以使用htons()
中的arpa/inet.h
,但我不是那种方法的忠实粉丝。我不认为名称与htobe16
一样清晰,并且您没有转换为/从little-endian字节顺序转换的函数。
答案 3 :(得分:-2)
最简单的sollution:使用十六进制值的整数形式,因此相应的二进制将产生相同的幻数!在这种情况下,这将是43605